DLL函数定义和函数实现写函数类型的不同, 引起不能使用Dll中的函数

<2011_0112>

/**

* 这个.h是给Dll的导出函数的头文件

*/

MY_DLL_API int __stdcall DoSomething(INT &nLen);

 

/**

* 实现文件

*/

MY_DLL_API int __stdcall DoSomething(DWORD &nLen)

{

//...

return S_OK;

}

 

/**

* def文件

*/

LIBRARY "xxlib"
DESCRIPTION  'xxLib Windows Dynamic Link Library'

EXPORTS

DoSomething

 

编译不报错, 等用到DoSomething函数时, 总是提示无法解决的外部函数.

工程中的函数名字起的比较长, 30几个字符长度. 入参4个, 这个写错的入参在最后一个.

 

自己折磨自己,花了5个小时来解决这个问题.

 

总结: 标准win32Dll, 导出的是内建类型. 都是全局函数, 编译时, 并不需要导出函数的头文件.

那个头文件是给调用者配合.lib一起使用的, 要是不用.h,和.lib, 就得动态调用.

 

还有一点,入参名称起名不好,引起的问题真不小. 要是原先是INT &nLen, 当长度不够,需要改变时, 应写成DWORD &dwLen,

如果是这样,问题能马上就发现.

 

不知道好习惯,是不是都是碰壁得来的...

 

回来做了个实验, 验证了这个问题.

函数的形参是由函数实现的形参决定的, 和导出函数头声明无关. 但是也能编译的过去,很怪的.

//MfcStdDllFrame_Export.h //MFCSTDDLLFRAME_EXPORT_H #ifndef MFCSTDDLLFRAME_EXPORT_H #define MFCSTDDLLFRAME_EXPORT_H #ifdef MFCSTDDLLFRAME_EXPORT #define MFCSTDDLLFRAME_API __declspec(dllexport) #else #define MFCSTDDLLFRAME_API __declspec(dllimport) #endif MFCSTDDLLFRAME_API int __stdcall test(INT & nLen); #endif

// MfcStdDllFrame.cpp : Defines the initialization routines for the DLL. // #include "stdafx.h" #include "MfcStdDllFrame.h" #include "MfcStdDllFrame_Export.h" /** * 1. test 原来在 MfcStdDllFrame_Export.h 中定义 * 和实现文件的入参不同 * 现在搬到实现文件中来, 居然也不报错. * 2. 在MfcStdDllFrame_Export.h中, 也声明 MFCSTDDLLFRAME_API int __stdcall test(INT & nLen); * 也能编译的过. * 不知道编译器怎么解释的? */ MFCSTDDLLFRAME_API int __stdcall test(INT & nLen); MFCSTDDLLFRAME_API int __stdcall test(DWORD & nLen) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return S_OK; } #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif BEGIN_MESSAGE_MAP(CMfcStdDllFrameApp, CWinApp) //{{AFX_MSG_MAP(CMfcStdDllFrameApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMfcStdDllFrameApp construction CMfcStdDllFrameApp::CMfcStdDllFrameApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CMfcStdDllFrameApp object CMfcStdDllFrameApp theApp;

; MfcStdDllFrame.def : Declares the module parameters for the DLL. LIBRARY "MfcStdDllFrame" DESCRIPTION 'MfcStdDllFrame Windows Dynamic Link Library' EXPORTS ; Explicit exports can go here test

// testDll.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "testDll.h" /** * 如果到调用已有Dll的时候,再自己改头文件声明,就没用了. * 用dumpbin来看Dll中的导出函数, 能看到函数名称, 看不到形参列表 */ //#include "MfcStdDllFrame_Export.h" /** * DLL生成时, 已经按照实现文件定义的形参生成了 MFCSTDDLLFRAME_API int __stdcall test(DWORD & nLen) * * 调用时, 如果声明成MFCSTDDLLFRAME_API int __stdcall test(INT & nLen); * 编译不过, error LNK2001: unresolved external symbol "int __stdcall test(int &)" (?test@@YGHAAH@Z) * * * */ #define MFCSTDDLLFRAME_API __declspec(dllexport) MFCSTDDLLFRAME_API int __stdcall test(DWORD & nLen); #pragma comment(lib, "MfcStdDllFrame.lib") #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object CWinApp theApp; using namespace std; int fnTestDll(); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else { // TODO: code your application's behavior here. CString strHello; strHello.LoadString(IDS_HELLO); cout << (LPCTSTR)strHello << endl; fnTestDll(); } return nRetCode; } int fnTestDll() { //INT nParam = 0; DWORD nParam = 0; //看来函数定义的形参名称起的不好, 存在的隐患还埋的很深 return test(nParam);//编译错误在这 } /** * 编译结果 * Linking... * testDll.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) int __stdcall test(int &)" (__imp_?test@@YGHAAH@Z) * Debug/testDll.exe : fatal error LNK1120: 1 unresolved externals * * 如果按照导出函数的实际实现的函数定义来声明, 必须是编译DLL时,就和函数实现的入参相同 * 就可以编译通过 * * rem dumpbin /ALL ./MfcStdDllFrame.dll > ./dumpbin_out.txt * dumpbin /EXPORTS ./MfcStdDllFrame.dll * * MFCSTDDLLFRAME_API int __stdcall test(DWORD & nLen) */

 

你可能感兴趣的:(DLL函数定义和函数实现写函数类型的不同, 引起不能使用Dll中的函数)