如何将C++对象传递给 C#
How to pass C++ Object to C#
向处理过C++和 C# 的有经验的人寻求帮助
我现在正在编写一个 C# 项目,该项目需要调用内部库中现有的 C++ 函数,并遇到了一些困难。
C++ 代码函数标头(无法更改(
typedef int (*PTR_func)
(const char* param1, // input
const char* param2, // input
VirtualInternalString& po_output); // Third param is actually the output
内部字符串对象的C++代码类(无法更改(
namespace InternalLib
{
class VirtualInternalString
{
public :
virtual ~VirtualInternalString(){};
virtual void _cdecl SetString(const char *) =0;
virtual const char * _cdecl c_str() const =0;
};
class SafeInternalString :public VirtualInternalString
{
public :
SafeInternalString():TheString(""){};
virtual ~SafeInternalString(){};
virtual void _cdecl SetString(const char * chararray) { TheString = chararray;};
virtual const char * _cdecl c_str() const { return TheString.c_str() ;} ; // This is the std::string
protected:
std::string TheString;
};
class SafePtrString :public VirtualInternalString
{
public :
SafePtrString():PtrString(0){};
SafePtrString(std::string &str):PtrString(&str){};
virtual ~SafePtrString(){};
virtual void _cdecl SetString(const char * chararray) { (* PtrString) = chararray;};
virtual const char * _cdecl c_str() const { return PtrString->c_str() ;} ;
protected :
std::string * PtrString;
};
}
现在,我必须在 C# 代码中使用此"func"。我可以正确调用和使用C++函数,但是在输出返回(第三个参数(期间出现问题。它应该是与问题相关的返回类型。
C#(可以更改(
[DllImport("xxxxlib", CallingConvention = CallingConvention.Cdecl)]
private extern static int func(string param1,
string param2,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder res); // problem here
我知道我必须创建一个适当的包装器来将 c++ 对象解码为 C# 字符串,但我以前没有这方面的经验。我已经尝试了互联网上的几种解决方案,但不起作用。
有人知道我如何实现这一点吗?你介意给我看一些简单的 C# 框架代码吗?
如果您只更改 C# 端,Vasek 的可能重复将不起作用。但是您可以做的是在C++中创建包装器,这些包装器创建具有关联length
参数的原始char *
。
创建一个附加的C++标头和源,其中包含:
int func
(const char* param1, // input
const char* param2, // input
char* po_output, // Third param is actually the output
int length); // Length of the buffer allocated by caller
然后你让你的func
打电话PTR_func
.
在这种情况下,我认为使用 C++/CLI 确实有意义。你可能希望在本机 C++ DLL 和 C# 代码之间构建一个微小的C++/CLI 桥接。
C++/CLI 层负责将自定义C++字符串类作为 DLL 函数的输出参数,并从此自定义字符串转换为 C#/.NET 字符串对象。
您的自定义C++字符串类似乎包装了std::string
;另一方面,C#/.NET 字符串使用 Unicode UTF-16 作为其文本编码,因此您可能需要在 Unicode UTF-8(存储在std::string
和自定义字符串类中(和 UTF-16(用于 C#/.NET 字符串(之间进行转换。
同样,还需要在此 C++/CLI 桥接层中将 C# UTF-16 字符串转换为 UTF-8,并将这些 UTF-8 编码的字符串作为const char*
输入参数传递给本机 DLL 函数。
使用 COM 并从 C# 代码中使用C++。仅当您在Windows平台上时。
根据过去的经验,我确实使用SWIG工具来实现生成包装器 它支持C++到多种语言的包装生成,其中Java是最受欢迎的语言 有一个很棒的教程 - http://www.swig.org/tutorial.html 还支持 C# - http://www.swig.org/Doc3.0/CSharp.html
/* InternalLib.i */
%module InternalLib
%{
/* include header with a VirtualInternalString class*/
#include "InternalLib.h"
%}
然后调用 swig 生成包装器文件:
swig -csharp InternalLib.i
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象