为啥 CString::LoadString 在我的应用程序的主模块(.exe)中有效,但在我的 extensionDLL 中无效?
Posted
技术标签:
【中文标题】为啥 CString::LoadString 在我的应用程序的主模块(.exe)中有效,但在我的 extensionDLL 中无效?【英文标题】:Why is it CString::LoadString works in the main module(.exe) of my app but will not work in my extensionDLL?为什么 CString::LoadString 在我的应用程序的主模块(.exe)中有效,但在我的 extensionDLL 中无效? 【发布时间】:2014-10-05 12:44:05 【问题描述】:我有这个 MFC 应用程序,它使用 CString::LoadString 函数从字符串资源加载字符串。每个应用程序对话框的类及其相关资源都包含在 MFC 扩展 DLL 中。
CString::LoadString 从主模块(.exe) 资源的字符串资源中加载字符串成功,但从DLL 资源的字符串资源中加载字符串失败。
在每种情况下,我通过调用从 CWinApp 对象获取加载字符串的实例句柄: CWinApp *WinApp = AfxGetApp(), 当然,实例的句柄是 WinApp->m_hInstance,我在调用 CString::LoadString 函数时将其用作第一个参数。
可能是什么原因以及解决方法。
【问题讨论】:
MFC LoadString in dll fails 的可能重复项 ***.com/questions/9062034/… 【参考方案1】:您是否通过 EXE 的 HINSTANCE 从扩展库加载字符串?听起来很像。
使用 MFC,如果您有扩展库并确保您的字符串标识符是唯一的,您只需要调用 CString::LoadString(UINT nID) 版本。因为扩展库创建进入全局链表的 CDynLinkLibrary 结构,所以 LoadString(UINT) 函数将搜索所有 MFC 库,直到找到包含该字符串的 HINSTANCE,然后从那里加载。如果您坚持使用带 HINSTANCE 参数的 LoadString() 函数,请务必在要从 DLL 加载字符串或对话框时使用扩展 DLL 的 HINSTANCE,而不是 EXE 的扩展。
对于小型项目,例如少于十几个 DLL,您可能设法只对所有内容使用唯一 ID。当您进入像 100 多个 DLL 之类的大型项目时,您必须使用其他技术,例如在您的 DLL 中调用 AfxSetResourceHandle() 的特殊命名函数,或者知道始终使用 DLL 的 HINSTANCE。那是另一个话题。
【讨论】:
【参考方案2】:为了补充 Joe Willcoxson 的回答,请务必检查您使用的每个 MFC 扩展 DLL 是否需要特殊的初始化代码,类似于下面的示例:
#include "stdafx.h"
#include <afxdllx.h>
static AFX_EXTENSION_MODULE MyExtDLL = NULL, NULL ;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
if (dwReason == DLL_PROCESS_ATTACH)
TRACE0("MyExt.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(MyExtDLL, hInstance))
return 0;
new CDynLinkLibrary(MyExtDLL);
else if (dwReason == DLL_PROCESS_DETACH)
TRACE0("MyExt.DLL Terminating!\n");
// Terminate the library before destructors are called
AfxTermExtensionModule(MyExtDLL);
return 1; // ok
此代码只负责创建 CDynLinkLibrary,这是在 MFC 模块之间共享资源的关键。
如果所有这些都设置正确 - 并且没有 ID 冲突 - 那么它只是一个调用的数学:
CString str;
str.LoadString(IDS_MY_STRING_ID);
代码中的任何位置,无论字符串实际存在于何处。
可以在link 中找到有关资源 ID 和编号的良好起点。
【讨论】:
以上是关于为啥 CString::LoadString 在我的应用程序的主模块(.exe)中有效,但在我的 extensionDLL 中无效?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在我的 UIPanGestureRecognizer 上调用 UILongPressGestureRecognizer 方法?
为啥在我第一次单击按钮时在我的 RecyclerView 中调用绑定?