包括C ++的C-DLL

这感觉就像一个noob问题,所以如果这是一个愚蠢的,请指出我到正确的位置:)

我试过把用C编写的DLL包含到C ++程序中。 它没有工作; gcc说

test.cpp:xxx:错误:函数的参数太多。

这是一个最小的工作示例:

DLL函数的包装器:

/* myWrapper.h */ #ifndef _MYWRAPPER_H #define _MYWRAPPER_H #include <windows.h> #ifdef __cplusplus extern "C" { #endif extern FARPROC EXPORTED_functionNameP; int GetDLLpointers(); #ifdef __cplusplus } #endif #endif 

其实施:

 /* myWrapper.c */ #include <windows.h> #include "myHeader.h" #ifdef __cplusplus extern "C" { #endif HINSTANCE drvsHANDLE; extern FARPROC EXPORTED_functionNameP; int GetDLLpointers() { static int result; drvsHANDLE = LoadLibrary("myLibrary.dll"); if (drvsHANDLE == NULL) return (result=0); EXPORTED_functionNameP = GetProcAddress( drvsHANDLE, "originalFunctionName"); if (EXPORTED_functionNameP == NULL) return (result = 0); return (result = 1); } #ifdef __cplusplus } #endif 

当然,我自己也没有写这些,也没有写图书馆,所以最好不要动。 但是我添加了extern "C"行。

那么,我的主要文件:

 // my Main #include <windows.h> #include "myHeader.h" int main(int argc, char **argv) { int arg = 1; EXPORTED_functionNameP(arg); return 0; } 

构build命令:

 gcc -I. -c -o myHeader.o myHeader.c -L. -lmyLibrary g++ -I. -o main.exe myMain.cpp myHeader.o -L. -lmyLibrary 

它工作正常,如果我重写我的main.cpp到有效的C和编译与gcc而不是g++

我试图将extern "C"改为extern "C++" ,但是我没有用到所有的排列或者gccg++

我知道这是与名称混搭有关,但是我认为当你包含extern "C"行时, gcc会照顾到这个问题……有人能解释我在这里失踪的内容吗?

万一它很重要 –

Windows XP专业版(稍后将会是Win7)

(MinGW)gcc 4.6.2

C和C ++是有区别的。

 int (FAR WINAPI * FARPROC) () 

在C中,FARPROC声明指出一个具有未指定参数列表的回调函数。 但是,在C ++中,声明中的空参数列表指示函数没有参数。

CallWindowProc的MSDN页面解释更多一点。

经过Google的快速搜索,似乎FARPROC被定义为:

 typedef int (FAR WINAPI *FARPROC)(); 

也就是说, FARPROC是一个返回一个int并且不带参数的函数。 所以你不能把它用于任何其他情况。

相反,像这样声明EXPORTED_functionNameP

 extern void (*EXPORTED_functionNameP)(int); 

现在EXPORTED_functionNameP是一个指向一个函数的指针,它接受一个int参数并且不返回任何值。

FARPROC类型是不带参数的函数的函数指针。 你应该像这样声明EXPORTED_functionNameP (用真正返回的函数替换void ):

 extern void (*EXPORTED_functionNameP)(int); 

并像这样初始化它(从GetProcAddress()返回的值几乎总是需要被转换成正确的类型):

 EXPORTED_functionNameP = (void (*)(int)) GetProcAddress(drvsHANDLE, "originalFunctionName"); 

功能类型的typedef可能会使事情更具可读性。

这是因为FARPROC被定义为:

 int (FAR WINAPI * FARPROC) () 

所以你不能在C ++中传递任何参数给这样的函数。 为了修复它,你应该定义EXPORTED_functionNameP作为指针,以DLL库中定义的相同的语义来运行。 例如:

 typedef (void* EXPORTED_functionNameP)(int value); EXPORTED_functionNameP ExportedFns; ... ExportedFns = GetProcAddress(drvsHANDLE, "originalFunctionName"); 

FARPROC被定义为

 typedef int (FAR WINAPI *FARPROC)(); 

当你传递一个额外的参数,虽然原型的参数列表是空的,你会得到错误。

您需要一个适当的PORTED_functionNameP原型定义, PORTED_functionNameP GetProcAddress的结果GetDLLPopinters函数中。