www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interfacing C++ to D --> or better: C++ --> C ---> D (DLL)

reply "BeschBesch" <d475502 drdrb.com> writes:
I want to use a set of functions that rely on a library which is 
not available for D (Harfbuzz). So I just wrote myself a set a 
functions that will do anything I need (Init, Free, Fonts, Text, 
etc).

The DLL is working fine and dynamically linking should work (it 
does in C++ --> LoadLibrary). Unfortunately, i get Error 42 
evertime i try to call a function.

As i suspected that some things written by me could be 
responsible for this, I build a test application with three 
functions (Test, Test2,Test3), got myself the D-.lib for 
statical-linking (implib-Dmd) and tried that one out. The result: 
Error 42.

What did I miss that can still cause linker errors? So far I did:

DLL is written in C (C89 --> VC++ only can afford that one it 
seems). And yes I changed it to C from C++ in the compiler 
settings.

DLL has an entry function AND a module-definition file (.def). A 
.lib-file is created alongside with the DLL (.def specified in 
porject settings). OF COURSE, I built a D-conform .lib by using 
implib with /s option (and without) /s option.

Thank you, if you are still reading.

CODE:
////// declared in Test.h
void Test1(void);
int Test2(int i);
long Test3(int* ptr);
////// Example implementation in Test.c (include "test.h"
void Test1(void)
{
	printf("FUNCTION WAS CALLED\n");
}
///// .def-File
LIBRARY "CtoDtestDll"
EXPORTS
Test1  1
Test2  2
Test3  3
/// SETTINGS (C++)
Calling-convention: __cdecl (= std. ??)
Compiling for:   C (/TC)
/// SETTINGS (LINKER)
Modul-definition-file: CTestDll.def....

////// D-Module for usage with .lib from .dll (implib! from bup)
module CoreFuncs; // just a name

pragma (lib,"CtoDtestDll.lib"); // statically linking (could user 
settings too)

extern (C)   /// needed so the compiler can link the functions
{

void Test();

}
Mar 29 2014
next sibling parent "BeschBesch" <d475502 drdrb.com> writes:
 extern (C)   /// needed so the compiler can link the functions
 {

 void Test();

 }
The function of course is called "Test1" not Test.
Mar 29 2014
prev sibling parent reply "evilrat" <evilrat666 gmail.com> writes:
On Saturday, 29 March 2014 at 15:03:18 UTC, BeschBesch wrote:
 I want to use a set of functions that rely on a library which 
 is not available for D (Harfbuzz). So I just wrote myself a set 
 a functions that will do anything I need (Init, Free, Fonts, 
 Text, etc).

 The DLL is working fine and dynamically linking should work (it 
 does in C++ --> LoadLibrary). Unfortunately, i get Error 42 
 evertime i try to call a function.

 As i suspected that some things written by me could be 
 responsible for this, I build a test application with three 
 functions (Test, Test2,Test3), got myself the D-.lib for 
 statical-linking (implib-Dmd) and tried that one out. The 
 result: Error 42.

 What did I miss that can still cause linker errors? So far I 
 did:

 DLL is written in C (C89 --> VC++ only can afford that one it 
 seems). And yes I changed it to C from C++ in the compiler 
 settings.

 DLL has an entry function AND a module-definition file (.def). 
 A .lib-file is created alongside with the DLL (.def specified 
 in porject settings). OF COURSE, I built a D-conform .lib by 
 using implib with /s option (and without) /s option.

 Thank you, if you are still reading.

 CODE:
 ////// declared in Test.h
 void Test1(void);
 int Test2(int i);
 long Test3(int* ptr);
 ////// Example implementation in Test.c (include "test.h"
 void Test1(void)
 {
 	printf("FUNCTION WAS CALLED\n");
 }
 ///// .def-File
 LIBRARY "CtoDtestDll"
 EXPORTS
 Test1  1
 Test2  2
 Test3  3
 /// SETTINGS (C++)
 Calling-convention: __cdecl (= std. ??)
 Compiling for:   C (/TC)
 /// SETTINGS (LINKER)
 Modul-definition-file: CTestDll.def....

 ////// D-Module for usage with .lib from .dll (implib! from bup)
 module CoreFuncs; // just a name

 pragma (lib,"CtoDtestDll.lib"); // statically linking (could 
 user settings too)

 extern (C)   /// needed so the compiler can link the functions
 {

 void Test();

 }
have you looked at exported symbols in dll? it may be C++ from what you said(lib not designed for C++?), so you can try extern(C++) on D side instead extern(C). or add manually #ifdef __cplusplus and extern "C" on lib side(if its not that big of course).
Mar 30 2014
parent reply "BeschBesch" <d475502 drdrb.com> writes:
 have you looked at exported symbols in dll? it may be C++ from 
 what you said(lib not designed for C++?), so you can try 
 extern(C++) on D side instead extern(C). or add manually #ifdef 
 __cplusplus and extern "C" on lib side(if its not that big of 
 course).
First of all: I started with a C++-dll and tried to declare the functions with extern (C++) --> did not work. Then I switched the compiler to C. As VC++ still uses only C89 as standard you can imagine there is NOTHING C++-ish that could have survived. I also tested this DLL in a C++-application (static) and it worked like a charm. ALSO:
 As i suspected that some things written by me could be 
 responsible for this, I build a test application with three 
 functions (Test, Test2,Test3), got myself the D-.lib for 
 statical-linking (implib-Dmd) and tried that one out. The 
 result: Error 42.
So, actually I am trying to get a DLL containing three single-line test functions to work. What I have already achieved is to load it dynamically, and it worked (Derelict.Util.Loader.SharedLibLoader Class). As I also use the Derelict-packages, I may intend to build a custom loader class as a work-around.
Mar 30 2014
parent "evilrat" <evilrat666 gmail.com> writes:
On Sunday, 30 March 2014 at 11:16:16 UTC, BeschBesch wrote:
 have you looked at exported symbols in dll? it may be C++ from 
 what you said(lib not designed for C++?), so you can try 
 extern(C++) on D side instead extern(C). or add manually 
 #ifdef __cplusplus and extern "C" on lib side(if its not that 
 big of course).
First of all: I started with a C++-dll and tried to declare the functions with extern (C++) --> did not work. Then I switched the compiler to C. As VC++ still uses only C89 as standard you can imagine there is NOTHING C++-ish that could have survived. I also tested this DLL in a C++-application (static) and it worked like a charm. ALSO:
 As i suspected that some things written by me could be 
 responsible for this, I build a test application with three 
 functions (Test, Test2,Test3), got myself the D-.lib for 
 statical-linking (implib-Dmd) and tried that one out. The 
 result: Error 42.
So, actually I am trying to get a DLL containing three single-line test functions to work. What I have already achieved is to load it dynamically, and it worked (Derelict.Util.Loader.SharedLibLoader Class). As I also use the Derelict-packages, I may intend to build a custom loader class as a work-around.
it is not clear for me what are you trying to achieve and where/what is error 42. do you want implicit loading? if so, have you tried converting lib using coffimpblib tool from ftp.digitalmars.com? keep in mind that you don't have to convert libs when building in 64 bit mode.
Mar 30 2014