c# - .NET DllImport 错误 EntryPointNotFoundException:将 AWS-Encryption-SDK 从 C 和 C++ 绑定到 C#
问题描述
我正在开发一个 .NET 5 项目,以使用 PInvoke、类型编组和 DllImportAttribute 将 AWS-Encryption-SDK 从 C 和 C++ 绑定到 C#。尝试调用此 C++ 函数时
aws_cryptosdk_keyring *Build(const Aws::String &generator_key_id, const Aws::Vector<Aws::String> &additional_key_ids = {}) const;
使用
[DllImport("aws-encryption-sdk-cpp.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern aws_cryptosdk_keyring Build(string generator_key_id, string[] additional_key_ids = null);
我收到这个错误
System.EntryPointNotFoundException:无法在 DLL“aws-encryption-sdk-cpp.dll”中找到名为“Build”的入口点。
此函数的 dll 签名是
?Build@Builder@KmsKeyring@Cryptosdk@Aws@@QEBAPEAUaws_cryptosdk_keyring@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$vector@V? $basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator @D@2@@std@@@2@@7@@Z
到目前为止,我没有尝试过,因为 EntryPoint 是成功的。有没有人有任何想法?
解决方案
扩展@jwezorek 的评论,C# 不知道如何调用 C++(类)函数,只知道 C 函数。这有几个原因,但我不会在这里讨论它们。
您需要(在 C++ 中)创建一个包装器,将每个 C++ 调用转换为“扁平化”C 调用。例如:
extern "C" void *createClass() {
return (void*) new myClass();
}
extern "C" void destroyClass(void* self) {
delete (myClass*) self;
}
extern "C" int callFunction1(void* self, int x, int y) {
return ((myClass*) self)->function1(x, y);
}
您需要为每个类函数(加上构造函数和析构函数)编写一个函数。然后编译,将其链接到原始 C++ DLL 的库。然后在 C# 中,编写一个包装器来调用您的扁平类:
public class myClass : IDisposable {
[DllImport("myFlattenedDll", EntryPoint="createClass")]
public static extern IntPtr createClass();
[DllImport("myFlattenedDll", EntryPoint="destroyClass")]
public static extern void destroyClass(IntPtr self);
[DllImport("myFlattenedDll", EntryPoint="callFunction1")]
public static extern int callFunction1(IntPtr self, int x, int y);
private IntPtr self;
public myClass() {
self = createClass();
}
~myClass() {
Dispose();
}
public virtual void Dispose() {
lock (this) {
destroyClass(self);
GC.SuppressFinalize(this);
}
}
public int callFunction1(int x, int y) {
return callFunction1(self, x, y);
}
}
您还应该研究一个名为SWIG的工具,它可以为您自动执行大量的包装器编码。
推荐阅读
- c++ - cpp中动态分配和普通指针的区别
- java - 微调器上的 Binder 事务失败
- .net - Reactor.Template 未安装(.NET SDK)
- python - 在 Selenium 中查看“a”锚标记是否包含我想要的文本,然后在同一行中提取多个 td 文本
- r - 如何使用 tidyverse 正确旋转表格?
- python - 如何在 google colab 中编写代码以重新运行所有脚本一定数量的迭代?
- c++ - 用字符串填充 argv(并获取 argc)以传递给其他方法
- ip - AzerothCore. 我可以在 realmlist 表中使用我的 DDNS 主机名吗?
- scip - 是否可以直接从 PyScipOpt 模型对象访问 SCIP 的统计输出值?
- go - 嵌入 FS 无法正确解析模板