digitalmars.D - Extern Linkage Type
Relatively new to D, experienced in other programming languages - especially mixed language programming. Below is code snippets of an extern statement and resulting error messages. finance.lib was created from implib, finance.dll was created by Free Pascal. dfinc.d is a simple MS-DOS proof of concept program that calls three of the functions in finance.pas. I am running into the same problem I had calling Silverfrost FORTRAN .dll's from D. The only linkage type that compiles error-free is Pascal, for calling subprograms in both FORTRAN .dll's and Pascal .dll's (obvious linkage type for Pascal, but that produces some other interesting problems - case insensitivity for procedure/function names and inverse parameter order passing; using a hex editor, was able to verify Free Pascal procedure/function names ARE case sensitive). The D program can only call those Free Pascal subprograms whose name is entirely upper case. Both the Silverfrost FORTRAN .dll's and the Free Pascal .dll's are using the stdcall call model. Can anyone please give me some insight? Possible solutions? Any insights would be appreciated - thanks. extern (C) { float CMPT_PV (ref short, ref short, ref float, ref float); float CMPT_FV (ref short, ref short, ref float, ref float); float NPVPROJCT (ref short, ref short, ref float[200], ref float[200], ref float, ref float); } dmd dfinc.d finance.lib OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html dfinc.obj(dfinc) Error 42: Symbol Undefined _CMPT_PV dfinc.obj(dfinc) Error 42: Symbol Undefined _CMPT_FV dfinc.obj(dfinc) Error 42: Symbol Undefined _NPVPROJCT --- errorlevel 3 *************************************** extern (C++) { float CMPT_PV (ref short, ref short, ref float, ref float); float CMPT_FV (ref short, ref short, ref float, ref float); float NPVPROJCT (ref short, ref short, ref float[200], ref float[200], ref float, ref float); } dmd dfinc.d finance.lib OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html dfinc.obj(dfinc) Error 42: Symbol Undefined ?NPVPROJCT YAMAAF0AAY0MI M1AAM2 Z (float cdecl NPVPROJCT(short &,short &,float [200]&,float [200]&,float &,float &)) dfinc.obj(dfinc) Error 42: Symbol Undefined ?CMPT_FV YAMAAF0AAM1 Z (float cdecl CMPT_FV(short &,short &,float &,float &)) dfinc.obj(dfinc) Error 42: Symbol Undefined ?CMPT_PV YAMAAF0AAM1 Z (float cdecl CMPT_PV(short &,short &,float &,float &)) --- errorlevel 3 *************************************** extern (D) { float CMPT_PV (ref short, ref short, ref float, ref float); float CMPT_FV (ref short, ref short, ref float, ref float); float NPVPROJCT (ref short, ref short, ref float[200], ref float[200], ref float, ref float); } dmd dfinc.d finance.lib OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html dfinc.obj(dfinc) Error 42: Symbol Undefined _D5dfinc9NPVPROJCTFKsKsKG200fKG200fKfKfZf dfinc.obj(dfinc) Error 42: Symbol Undefined _D5dfinc7CMPT_FVFKsKsKfKfZf dfinc.obj(dfinc) Error 42: Symbol Undefined _D5dfinc7CMPT_PVFKsKsKfKfZf --- errorlevel 3 *************************************** extern (Windows) { float CMPT_PV (ref short, ref short, ref float, ref float); float CMPT_FV (ref short, ref short, ref float, ref float); float NPVPROJCT (ref short, ref short, ref float[200], ref float[200], ref float, ref float); } dmd dfinc.d finance.lib OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html dfinc.obj(dfinc) Error 42: Symbol Undefined _NPVPROJCT 24 dfinc.obj(dfinc) Error 42: Symbol Undefined _CMPT_PV 16 dfinc.obj(dfinc) Error 42: Symbol Undefined _CMPT_FV 16 --- errorlevel 3 *************************************** extern (System) { float CMPT_PV (ref short, ref short, ref float, ref float); float CMPT_FV (ref short, ref short, ref float, ref float); float NPVPROJCT (ref short, ref short, ref float[200], ref float[200], ref float, ref float); } dmd dfinc.d finance.lib OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html dfinc.obj(dfinc) Error 42: Symbol Undefined _NPVPROJCT 24 dfinc.obj(dfinc) Error 42: Symbol Undefined _CMPT_PV 16 dfinc.obj(dfinc) Error 42: Symbol Undefined _CMPT_FV 16 --- errorlevel 3
Jun 15 2015
On Tuesday, 16 June 2015 at 07:47:21 UTC, Kagamin wrote:implib works for C calling convention only.Thank you for your reply. So if I am understanding correctly (feel free to admit my ignorance): 1. implib is required to generate a dmd compatible import library from an .dll 2. implib only works for C calling convention only Therefore, D can only call C and D compatible .dll's? Obviously I am being dumb about something, because learning and playing around with D I have written several windows programs (XP and 7) that call Silverfrost FORTRAN .dll's (please see http://rrroberts.50webs.com/cobindex.htm) using extern (Pascal) {...}. The FORTRAN .dll's were produced by the Silverfrost SLINKER, then produced an .lib file from that .dll using DMD's implib. And I am now doing the same thing with Free Pascal. And before anyone says COBOL and FORTRAN are dead, COBOL is still widely used in banking back-end applications, and FORTRAN is used in engineering applications. Again thanks for your reply.
Jun 17 2015
D, like C, can call dll with proper import library, it's just implib can't produce one.
Jun 18 2015
On Thursday, 18 June 2015 at 07:52:02 UTC, Kagamin wrote:D, like C, can call dll with proper import library, it's just implib can't produce one.OK, Thanks people, you gave me a things to think about..
Jun 18 2015
On Wednesday, 17 June 2015 at 20:33:04 UTC, Rodney wrote:On Tuesday, 16 June 2015 at 07:47:21 UTC, Kagamin wrote:I believe you can declare cdecl wrappers on free pascal or fortran side, so they will have C calling convention and no mangling. For example: procedure procedure_name(arg : ArgType); cdecl; *forward arguments to original procedure* function function_name(arg : ArgType): ReturnedType; cdecl; *forward arguments to original function* And then on D side: extern(C) void procedure_name(ArgType arg); extern(C) ReturnedType function_na,e(ArgType arg);implib works for C calling convention only.Thank you for your reply. So if I am understanding correctly (feel free to admit my ignorance): 1. implib is required to generate a dmd compatible import library from an .dll 2. implib only works for C calling convention only Therefore, D can only call C and D compatible .dll's? Obviously I am being dumb about something, because learning and playing around with D I have written several windows programs (XP and 7) that call Silverfrost FORTRAN .dll's (please see http://rrroberts.50webs.com/cobindex.htm) using extern (Pascal) {...}. The FORTRAN .dll's were produced by the Silverfrost SLINKER, then produced an .lib file from that .dll using DMD's implib. And I am now doing the same thing with Free Pascal. And before anyone says COBOL and FORTRAN are dead, COBOL is still widely used in banking back-end applications, and FORTRAN is used in engineering applications. Again thanks for your reply.
Jun 18 2015