c++调用dll 与 c调用dll
//lib.h#ifndefLIB_H#defineLIB_Hextern"C"_declspec(dllexport)intadd(intx,inty);#endif/...
//lib.h
#ifndef LIB_H
#define LIB_H
extern "C" _declspec(dllexport) int add(int x,int y);
#endif
//lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x+y;
}
解决方案生成lib.dll
调用:
typedef int (*addfun)(int ,int );
.........
HINSTANCE hDll=NULL;
addfun add;
hDll=LoadLibrary(__T("lib.dll"));
if (hDll!=NULL)
{
add=(addfun)GetProcAddress(hDll,"add");
cout<<add(2,3);
}
疑问:
这里是采用c方式命名函数,函数不变,调用时直接取"add",如果去掉ertern "C",如何调用add函数?
理由:采用stdcall方式定义add函数的话,dll导出的函数名必定是c++内部命名方式,而非add,这样的调用时就不能GetProcAddress(hDll,"add")这样写了,怎么办? 展开
#ifndef LIB_H
#define LIB_H
extern "C" _declspec(dllexport) int add(int x,int y);
#endif
//lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x+y;
}
解决方案生成lib.dll
调用:
typedef int (*addfun)(int ,int );
.........
HINSTANCE hDll=NULL;
addfun add;
hDll=LoadLibrary(__T("lib.dll"));
if (hDll!=NULL)
{
add=(addfun)GetProcAddress(hDll,"add");
cout<<add(2,3);
}
疑问:
这里是采用c方式命名函数,函数不变,调用时直接取"add",如果去掉ertern "C",如何调用add函数?
理由:采用stdcall方式定义add函数的话,dll导出的函数名必定是c++内部命名方式,而非add,这样的调用时就不能GetProcAddress(hDll,"add")这样写了,怎么办? 展开
展开全部
1.__stdcall
以“?”标识函数名的开始,后跟函数名; 函数名后面以“@@YG”标识参数表的开始,后跟参数表;
参数表以代号表示: X--void , D--char, E--unsigned char, F--short, H--int, I--unsigned int, J--long, K--unsigned long, M--float, N--double, _N--bool, .... PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复;
参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;
参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。 其格式为“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”, 例如 int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z” void Test2() -----“?Test2@@YGXXZ”
2 __cdecl调用约定: 规则同上面的 _stdcall 调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。
3 __fastcall调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。
VC++对函数的省缺声明是"__cedcl",将只能被C/C++调用。
这是C++编译时的函数改名规则,c++函数改名主要是为了函数重载,而在C中不存在函数重载的问题,可以看出C++编译后函数的新名字很复杂。
所以只能通过extern来声明C函数编译命名规则来调用DLL中的导出函数
以“?”标识函数名的开始,后跟函数名; 函数名后面以“@@YG”标识参数表的开始,后跟参数表;
参数表以代号表示: X--void , D--char, E--unsigned char, F--short, H--int, I--unsigned int, J--long, K--unsigned long, M--float, N--double, _N--bool, .... PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复;
参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;
参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。 其格式为“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”, 例如 int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z” void Test2() -----“?Test2@@YGXXZ”
2 __cdecl调用约定: 规则同上面的 _stdcall 调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。
3 __fastcall调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。
VC++对函数的省缺声明是"__cedcl",将只能被C/C++调用。
这是C++编译时的函数改名规则,c++函数改名主要是为了函数重载,而在C中不存在函数重载的问题,可以看出C++编译后函数的新名字很复杂。
所以只能通过extern来声明C函数编译命名规则来调用DLL中的导出函数
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询