c++ 中的字符串?
我的问题是,我在 DLL 中有一些函数,其中一些函数例如:
#include <string>
using namespace std;
extern "C" __declspec(dllexport) string __cdecl encryption(string s)
{
return s;
}
每当我尝试从 C# 调用此函数时,这是我使用的代码:
[DllImport("Packer.dll", EntryPoint = "encryption")]
static extern string encryption(string s);
我收到错误: 对 PInvoke 函数“Packer”的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。
我猜我收到此错误是因为我没有正确的函数声明 谁能指导我如何解决这个问题,提前致谢
My problem is , i have some functions in a DLL some of these functions are for example :
#include <string>
using namespace std;
extern "C" __declspec(dllexport) string __cdecl encryption(string s)
{
return s;
}
Whenever i try to call this function from C# , here is the code im using :
[DllImport("Packer.dll", EntryPoint = "encryption")]
static extern string encryption(string s);
i get an error :
A call to PInvoke function 'Packer' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
im guessing i get this error because i dont have the right declarations for the function
can anyone guide me how to fix that , thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
std::string
不能与 PInvoke 一起使用,因为 C++ 没有为其对象提供正确清理堆栈、复制对象等所需的 ABI。这是 C++ 最大的痛苦之一。您必须使用
char*
指针和纯 C API。简而言之,PInvoke 不适用于 C++。std::string
can not be used with PInvoke, because C++ does not have an ABI for its objects which is required to properly clean stack, copy objects, etc. This is one of the greatest pains of C++.You have to use
char*
pointers and plain C APIs. Simply put, PInvoke does not work with C++.我相信您已经知道,C++
std::string
实际上是一个模板。仅当模板被实例化时(在本例中为std::basic_string
),该类型的对象的确切布局和方法的签名由 C++ 编译器确定。不幸的是,只有相关的 C++ 编译器才能访问所有相关信息(例如模板源代码)来做出此类决策。这就是为什么模板等非 C 功能即使在不同的 C++ 编译器之间通常也不能“转移”,更不用说 C++ 和 C# 了。
此外,C++ 名称通常以 C++ 编译器特定的方式“损坏”。
您必须更改本机方法的签名,以便它成为“纯”C 函数:
extern "C"
(您是已经在这样做了)。char*
参数而不是std::string
。char*
结果而不是std::string
,但为 非常小心你的做法。DllImportAttribute.CallingConvention
与 C 中的__cdecl
、__stdcall
或__fastcall
匹配。As I'm sure you already know, the C++
std::string
is actually a template. Only when the template is instantiated (asstd::basic_string<char>
in this case), the exact layout of the objects of that type and signatures of the methods are determined by the C++ compiler.Unfortunately, only the C++ compiler in question has the access to all the relevant information (such as template source code) to make these kinds of decisions. That's why non-C features such as templates are generally not "transferable" even between different C++ compilers, let alone C++ and C#.
Also, C++ names are typically "mangled" in a C++ compiler-specific manner.
You'll have to change the signature of your native method, so it is becomes a "pure" C function:
extern "C"
(you are already doing that).char*
parameter instead ofstd::string
.char*
result instead ofstd::string
, but be very careful how you do it.DllImportAttribute.CallingConvention
matches the__cdecl
,__stdcall
or__fastcall
in your C.这里的问题是,您使用的是 C# 不知道如何封送的 STL
string
类。这里有两个选择:char *
缓冲区。或者编写一个包装器或重载或使用char *
而不是string
的内容。The problem here is, you're using the STL
string
class which C# doesn't know how to marshal. You have two options here:char *
buffers. Or write a wrapper or an overload or something that useschar *
instead ofstring
.System::String
and calls the STL string versions internally.如果内存可用,如果您没有另外指定,P/Invoke 假定调用约定为
__stdcall
。如果是这样,将__cdecl
更改为__stdcall
应该可以解决第一个问题。正如@Adam Rosenfield 指出的那样,您可能还需要传递并返回一个
char const *
,而不是string
。 C# 和 C++ 几乎肯定对字符串的构成有一些不同的想法。If memory serves, if you don't specify otherwise P/Invoke assumes the calling convention is
__stdcall
. If so, changing your__cdecl
to__stdcall
should fix the first problem.As @Adam Rosenfield points out, you probably also need to pass and return a
char const *
, not astring
. C# and C++ almost certainly have somewhat different ideas of what constitutes a string.