大家好。我必须使用旧的实用程序:它将 xls 转换为 txt。实用程序的逻辑存在一个小问题,但问题出在其他方面......该实用程序由两部分组成:exe 模块和 dll 模块,并使用 MFC。
在 exe 项目中,我们有
pInit = (t_bXR_Init)GetProcAddress(hExcel, _T("bXR_Init"));
和
pInit("logfiles",false);
在 dll 项目中,我们有
typedef bool (*t_bXR_Init) (CString const &strlogfilespath, bool btxtfile);
XLSREADER_API bool bXR_Init(CString const &strlogfilespath, bool btxtfile);
问题是,当我们将参数"logfiles"
发送到函数中时,它没有得到它。这很奇怪,因为所有其他参数都正确发送。
原因与使用 CString 有关。但我不知道怎么做...
XLSREADER_API定义为:
#define XLSREADER_API extern "C" __declspec(dllimport)
我还添加了
AFX_MANAGE_STATE(AfxGetStaticModuleState());
在函数主体的开头(用于bXR_Init(。但这并没有帮助。
我也尝试更改这两个项目的一些设置,所有设置都相同(例如调用转换是 __cldecl(/Gd(;我同时构建调试版本 exe 和 dll 或发布版本的 exe 和 dll(。
我也尝试使用CString
而不是CString&
- 同样的情况。如果使用char*
它可以正常工作,但老板说首先要找到问题的根源。
什么可能导致问题(函数没有获得 CString 参数(?
若要跨 DLL 边界传递复杂类型(如 CString(,必须确保 DLL 和 exe 都使用完全相同的 DLL 库。将"运行时库"设置为多线程 DLL,并将"使用 MFC"设置为在共享 DLL 中使用 MFC。此外,不要混合使用调试模块和发布模块:两者必须相同。
如果没有这些条件,您将获得两个不同的堆,并且无法使分配/删除与两个堆兼容。
尝试将实际的CString
参数传递给调用:
CString sPath = "logfiles";
pInit(sPath,false);
wtfigo!(F是怎么回事(
问题解决了。
我发现,exe项目有"字符集"="使用多字节字符集"DLL项目有"字符集"="使用Unicode字符集"。
因此,dll 函数在 char* 中获得了 CString,但将其视为内部带有 wchat_t* 的 CString。它看起来像垃圾(在我的电脑上完全是垃圾,在我同事的电脑上是中文符号(。
我将exe项目的"字符集">更改为"使用unicode字符集",并发现了大约60个错误。然后我读了一篇文章 http://habrahabr.ru/post/164193/(俄语;或英语:http://www.codeproject.com/Articles/76252/What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc(。
并修复了所有错误,广泛使用的宏来自TCHAR.h(MSDN帮助了我(。
谢谢大家的帮助。