You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Visual C++ DLL项目使用cpprestsdk时出现动态链接库入口点无法定位问题

解决VC++ DLL中使用cpprestsdk时的“无法定位入口点”问题

兄弟,我之前在VC++里搞DLL加cpprestsdk(Casablanca)的时候,也碰到过一模一样的“无法定位入口点”坑,踩了好几个小时才爬出来。结合踩坑经验,这几个方向肯定能帮你解决问题:

1. 先把导出符号的写法改规范

你现在直接在静态方法上写__declspec(dllexport),虽然能导出,但很容易因为编译场景(是编译DLL还是调用DLL)搞混符号。最好用宏来区分:
在你的RestWrapper.h里改成这样:

#pragma once
// 用宏区分导出/导入
#ifdef MYCPPREST_EXPORTS
#define MYCPPREST_API __declspec(dllexport)
#else
#define MYCPPREST_API __declspec(dllimport)
#endif

namespace mycpprest {
class RestWrapper {
public:
    static MYCPPREST_API void TestApi();
};
}

然后去你的DLL项目属性里,找到C/C++ -> 预处理器 -> 预处理器定义,添加MYCPPREST_EXPORTS这个宏。这样编译DLL时自动导出符号,调用DLL的项目会自动导入,不会乱。

另外,你可以用VC自带的dumpbin /exports YourDll.dll命令(在VS的开发者命令提示符里运行),看看TestApi是不是在导出列表里。如果不在,说明导出写法有问题,比如漏加宏或者命名空间的影响(静态方法带命名空间的话,导出符号会是类似?TestApi@RestWrapper@mycpprest@@SAXXZ的格式,这是正常的)。

2. 必须匹配cpprestsdk的链接方式(静态/动态)

这是最容易踩的坑!cpprestsdk分静态和动态两种编译版本,必须和你的DLL项目的CRT链接方式完全匹配:

  • 如果你的DLL用的是动态CRT(项目属性->C/C++->代码生成->运行库:多线程DLL (/MD)多线程调试DLL (/MDd)),那你必须用动态版本的cpprestsdk,链接cpprest_2_10.lib(Release)或cpprestd_2_10.lib(Debug)。
  • 如果你的DLL用的是静态CRT/MT/MTd),那必须用静态版本的cpprestsdk,链接cpprestsdk_2_10.lib(Release)或cpprestsd_2_10.lib(Debug)。
  • 还要注意x86/x64、Debug/Release的配置完全一致,比如你DLL是x64 Debug,就不能用x86 Release的cpprest库,否则肯定会出现入口点找不到的问题。

3. 检查cpprestsdk的依赖DLL是否部署到位

如果你用的是动态版本的cpprestsdk,那你的DLL依赖的cpprestsdk的DLL(比如cpprest_2_10.dll)必须和你的DLL在同一个目录,或者在系统PATH里。如果缺失这个DLL,系统会找不到cpprest的符号,也会弹出“无法定位入口点”的错误。
调试的时候,直接把cpprest的DLL复制到你的DLL输出目录就行;发布的时候要记得一起打包这些依赖文件。

4. 确认cpprestsdk的库已经正确链接

你的RestWrapper.cpp里用到了cpprest的代码,那必须确保DLL项目已经链接了cpprest的库:
去项目属性的链接器->输入->附加依赖项里,添加对应的cpprest库文件(比如Debug下加cpprestd_2_10.lib),还要把cpprestsdk的库路径加到链接器->常规->附加库目录里。

最后给你个完整的RestWrapper.cpp示例,确保cpprest的代码能正常运行:

#include "stdafx.h"
#include "RestWrapper.h"
#include <cpprest/http_client.h>
#include <cpprest/json.h>

using namespace utility;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;

namespace mycpprest {
void RestWrapper::TestApi() {
    // 简单的示例请求,验证cpprest是否正常工作
    http_client client(U("https://jsonplaceholder.typicode.com/"));
    client.request(methods::GET, U("todos/1"))
        .then([](http_response response) {
            if (response.status_code() == status_codes::OK) {
                return response.extract_json();
            }
            return pplx::task<value>([] { return value(); });
        })
        .wait();
}
}

内容的提问来源于stack exchange,提问作者noyruto88

火山引擎 最新活动