int Set(CANMsg &CANObj)
我必须从c#调用上面的方法。直到现在我已经定义了一个包装器:
extern "C" __declspec(dllexport) int SetWrapper(CANMsg CANObj);
CANMsg CANObj ---这个参数是ok还是应该使用CANMsg * CANObj?
在这里我实现了包装器:
extern "C" __declspec(dllexport) int SetWrapper(CANMsg CANObj)
{
return Set(CANObj);
}
我正在创建这个包装器,因为这是函数的重载版本,我不得不以某种方式发挥作用。
这是CANMsg类:
class CANMsg
{
public:
CANMsg();
~CANMsg();
void AddRef() const;
void Release() const;
unsigned int MsgId;
unsigned int DLC;
unsigned int Handle;
unsigned int Interval;
unsigned int TimeStamp;
unsigned char Data0;
unsigned char Data1;
unsigned char Data2;
unsigned char Data3;
unsigned char Data4;
unsigned char Data5;
unsigned char Data6;
unsigned char Data7;
protected:
mutable int refCount;
};
现在,在C#中我有以下内容:
[StructLayout(LayoutKind.Sequential)]
public class CANmsg
{
public int MsgId;
public int DLC;
public int Handle;
public int Interval;
public int TimeStamp;
public char Data0;
public char Data1;
public char Data2;
public char Data3;
public char Data4;
public char Data5;
public char Data6;
public char Data7;
}
,导入是这样的:
[DllImport("engine.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int SetWrapper(IntPtr canMSGObject);
我对CANMsg对象有点困惑,我是否认为它是正确的IntPtr,是元帅,还是类型?如果我喜欢它,使用IntPtr,我应该在那里执行什么样的实例化?如果我发送一个CANMsg对象,我会收到有关一些无效参数的错误。
如果您需要更多详细信息,请与我们联系。
答案 0 :(得分:1)
您无法像这样将C#对象传递给本机C ++。 Marshal.StructureToPtr是您所需要的,详细信息和示例是here
答案 1 :(得分:1)
当我看到你的C ++类定义时,我会问自己"在构造函数和析构函数中会发生什么?"和" AddRef()
和Release()
做了什么?"这些都是重要的问题,因为您不能简单地将数据从C#对象投影到IntPtr上,并希望获得最佳效果。相反,你应该考虑制作一个帮助你的助手dll。你可能需要这样的方法:
public ref class MyLibraryHelper {
public:
IntPtr MakeCANMsg() { return gcnew IntPtr(new CANMsg()); }
void DestroyCANMsg(IntPtr msgPtr) {
CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
if (msg) delete msg;
}
void ProjectTo(CSharpCANMsg ^csh, IntPtr msgPtr)
{
CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
if (!msg) return;
msg->MsgId = csh->get_MsgId();
// etc
}
void ProjectFrom(IntPtr msgPtr, CSharpCANMsg ^csh)
{
CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
if (!msg) return;
csh->set_MsgId(msg->MsgId);
// etc
}
}
我的C ++ / CLI生锈了,所以期待一些问题。如果这看起来像是手工编组,那么,这是因为鉴于你已经暴露过的课程,你似乎需要它。
老实说,你可能不想要这个。实际上,您需要一个C ++ / CLI类来构造一个CANMsg并将其保存为私有成员,然后将.NET属性映射到较低级别的对象上。这种类必须是一次性的,!ClassName()
析构函数将负责删除底层对象。