met*_*hod 1 c# c++ string pinvoke
我的问题是,我在DLL中有一些函数,其中一些函数是例如:
#include <string>
using namespace std;
extern "C" __declspec(dllexport) string __cdecl encryption(string s)
{
return s;
}
Run Code Online (Sandbox Code Playgroud)
每当我尝试从C#调用此函数时,以下是使用的代码:
[DllImport("Packer.dll", EntryPoint = "encryption")]
static extern string encryption(string s);
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:调用PInvoke函数'Packer'使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
我猜我得到这个错误,因为我没有正确的功能声明任何人都可以指导我如何解决这个问题,提前谢谢
std::string 不能与PInvoke一起使用,因为C++没有为其对象提供ABI,这是正确清理堆栈,复制对象等所必需的.这是C++最大的痛苦之一.
您必须使用char*指针和纯C API.简而言之,PInvoke不适用于C++.
我相信你已经知道,C++ std::string实际上是一个模板.只有在实例化模板时(如std::basic_string<char>本例所示),该类型对象的确切布局和方法的签名由C++编译器确定.
不幸的是,只有相关的C++编译器才能访问所有相关信息(例如模板源代码)来做出这些决定.这就是为什么即使在不同的C++编译器之间,模板之类的非C功能通常也不能"转移",更不用说C++和C#了.
此外,C++名称通常以特定于C++编译器的方式"损坏".
你必须改变你的原生方法的签名,所以它变成了一个"纯粹的"C函数:
extern "C"(您已经在执行此操作),确保没有C++名称损坏.char*参数代替std::string.char*结果而不是std::string,但要非常小心你如何做到这一点.DllImportAttribute.CallingConvention匹配__cdecl,__stdcall或__fastcall在你的C.