使用 CString 进行 PInvoke
我正在尝试使用 P/Invoke 从 C# 调用非托管 C++ DLL 中的函数。 C++ DLL 使用 CString 作为函数参数并返回,例如
CString AFX_EXT_API GetUserName(CString& userID)
不幸的是,C++ 是遗留代码,我无法更改它以使用更通用的 LPSTR(甚至 <代码>字符*)。
有没有办法将 CString 编组为 .NET 兼容对象?或者以某种方式装饰 .NET char[]
以编组到 CString?
I'm trying to use P/Invoke to call functions in an unmanaged C++ DLL from C#. The C++ DLL uses CString
's as function parameters and returns, such as
CString AFX_EXT_API GetUserName(CString& userID)
Unfortunately, the C++ is legacy code that I cannot change to use the more universal LPSTR
(or even char *
).
Is there any way to marshal the CString into a .NET compatible object? Or somehow decorate a .NET char[]
to be marshaled to a CString?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法在托管代码中创建
CString
。显然,您需要在托管代码和本机代码之间添加一个额外的层。这使您有机会制作位于两者之间的 C++/CLI DLL。您可以从托管程序集中调用此代码,而无需 P/invoke。您可以从 C++/CLI 中间层创建一个
CString
。不过,有一点需要注意。您必须使用与本机 DLL 相同的 C++ 运行时。这或许是可能的,但很可能会成为绊脚石。例如,如果 DLL 是使用 MSVC6 编写的,那么您也需要使用 MSVC6 构建中间层,这就排除了 C++/CLI。在这种情况下,回到 P/invoke 和 char* 。
我要强调的是,导出基于 CString 的 DLL 接口是一种糟糕的做法,我正在寻找 DLL 的替代方案。
You can't create a
CString
in managed code. So clearly you need an extra layer between the managed code and the native code.This gives you an opportunity to make a C++/CLI DLL which sits between. You can call this code from your managed assembly without needing P/invoke. And from the C++/CLI middle layer you can create a
CString
.However, there is one caveat. You must be using the same C++ runtime as the native DLL. This may be possible but it is quite likely that it will be a stumbling block. For example if the DLL was written with MSVC6 then you will need to build your intermediate layer with MSVC6 too and that rules out C++/CLI. Back to P/invoke and
char*
in that case.I would stress that it is terrible practice to export a DLL interface based on
CString
and I'd be looking for alternatives to the DLL.如果您无法更改 DLL 本身,那么显而易见的选择是编写一个代理 DLL,它接受 char[],分配一个 CString,然后调用该 DLL。
If you can't change the DLL itself, the obvious choice is writing a proxy DLL which would accept char[], allocate a CString and then call the DLL.