我想编写一个非常非常小的程序来解析启动参数并选择几个 DLL 之一“启动”。
我已经编写了一个应用程序,我希望将其作为 DLL“运行”,方法是将其编写为应用程序,然后更改 Visual Studio 项目属性以将其构建为 DLL。我知道我需要同时使用 LoadLibrary 和 GetProcAddress 来获得我想要的功能,但我很难找到关于此的清晰而全面的文档,因为很多用例并不是真正的这种性质。另外,我必须根据项目和平台限制走这条路。
我找到了 this page ,其中有一些信息,但不够清晰,无法根据我的目的进行调整。
编辑:这是我现在所在的位置。
我有一个 DLL 项目,其主要函数签名如下所示:
__declspec(dllexport) int cdecl main(int argc, char *argv[])
我还有一个应用程序项目,它尝试加载 DLL 并运行上述函数,如下所示:
typedef int (CALLBACK* LPFNDLLFUNC1)(int, char *);
...
HMODULE dllHandle = NULL;
BOOL freeResult, runTimeLinkSuccess = FALSE;
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
if (args->IsEmpty())
{
dllHandle = LoadLibrary(L"TrueApplication.dll");
if (NULL != dllHandle)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(dllHandle, "main");
if (lpfnDllFunc1)
{
int retVal = lpfnDllFunc1(0, "1");
}
目前,LoadLibrary 调用有效,但 GetProcAddress 无效。
最佳答案
首先,将项目类型从可执行文件更改为DLL 不足以制作DLL。您还需要导出一些符号来创建您的 API。至少,您需要使用 __declspec(dllexport)
修饰要导出的函数。但是,我建议您导出 C API,这意味着 extern "C"
函数具有与 C
兼容的参数。因此,您导出的函数应该以 extern "C"__declspec(dllexport)
开头。
完成后,您可以像这样动态加载 DLL:
const char* dllname = "myfile.dll";
h = LoadLibrary(dllname);
if( h == nullptr )
{
/*handle error*/
}
using myfunc_type = bool (*)(int x, double y); //example
auto myfunc = reinterpret_cast<myfunc_type>(GetProcAddress(h, "myfunc"));
//......
myfunc(x,y); //call the imported function
此解决方案比 Jerry Coffin 展示的使用 /delayload
进行静态加载需要更多的工作,但它有一个优势:如果需要 DLL 但未找到,您可以向用户提供您自己的错误消息依赖来自 Windows 的消息(这对于非技术人员来说通常是 Not Acceptable )。您还可以在 API 中包含 API 版本验证及其自己的自定义错误消息。
编辑:如果您这样更改,代码示例将起作用
extern "C" __declspec(dllexport) int main(int argc, char *argv[]){...}
typedef int (* LPFNDLLFUNC1)(int, char **);
关于c++ - 我怎样才能在运行时像可执行文件一样 "start"DLL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40939319/