是否可以使用 C# DllImport 从 DLL 导入非托管类或结构
Is it possible to import unmanaged class or struct from DLL using C# DllImport?
正如msdn http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx说"平台调用服务(PInvoke)允许托管代码调用在DLL中实现的非托管函数。我想从 DLL 导入我在 c++
中创建的一些类可能吗?
例如,我在 DLL 中有一些结构:
struct __declspec(dllexport) DLLVector3
{
float x, y, z;
};
struct __declspec(dllexport) DLLQuaternion
{
float x, y, z, w;
};
class __declspec(dllexport) DLLCharacter
{
public:
DLLVector3 position;
DLLQuaternion orientation;
DLLCharacter()
{
}
~DLLCharacter()
{
}
void setPosition(PxVec3 pos)
{
position.x = pos.x;
position.y = pos.y;
position.z = pos.z;
}
void setOrientation(PxQuat or)
{
orientation.x = or.x;
orientation.y = or.y;
orientation.z = or.z;
orientation.w = or.w;
}
};
struct __declspec(dllexport) PhysicalObject
{
DLLCharacter *character;
PxRigidActor *mActor;
PxController *mController;
};
我可以通过哪种方式导入这些内容?尤其是那些带有指针的结构
您无需编写C++托管代码即可访问 - 但是 - 您不能轻松地在非托管内存和托管内存之间跳来跳去。 以下是几个关键点1) 使用 [StructLayout(LayoutKind.Sequential)] 定义映射在 c++ 结构之上的 .net 类
[StructLayout(LayoutKind.Sequential)] [Serializable] public struct SFVec3F : IRawStreamIO { public double _x; public double _y; public double _z; }
2)基本类型,如双精度,int32等,可以有效地在P/Invoke层中移动 - 更复杂的类型可以为您赢得thunking的.net变体 - msft doco涵盖了哪些数据类型可以有效地移动,请尝试使用它们
3)C++土地上的指针都是.net土地中的IntPtr,如果你想安全,你应该把它当作一个句柄,即你让c ++端做任何操作/访问底层结构
4)访问本机C++非常简单(句柄道具是最初来自本机C++端的IntPtr)
[DllImport("CS2V3.dll", CharSet = CharSet.Ansi)]
private static extern void AddChild(IntPtr csoPtr, IntPtr childPtr, short recomputeBounds, short adjustCoords, short blindchild);
public void AddChild(V3CSO theChild)
{
AddChild(m_handle, theChild.Handle,0,0,0);
}
5) 字符串和其他一些类型需要编组才能获得 .net 可用形式 - 请注意,当您将字符串传递给非托管代码时,字符串会自动发生这种情况,但您必须在入站时自己执行此操作
[DllImport("CS2V3.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetName(IntPtr csoPtr);
[DllImport("CS2V3.dll", CharSet = CharSet.Ansi)]
private static extern void SetName(IntPtr csoPtr, string newName);
public string Name { get { IntPtr np = GetName(m_handle); return Marshal.PtrToStringAnsi(np); } set { SetName(m_handle, value); } }
可能的。但是您需要在 C++/CLI 中编写包装器代码。这允许您编写可从 C#/.net 代码使用的类(外部是托管代码),并且在实现中可以使用C++代码。
不能直接导入C++类。只有 C 样式函数。C 样式函数只允许您传递 C 基元类型,这使得与它们的互操作变得容易。通常,从非C++代码中,几乎不可能正确传入C++类型。如果无法传入C++对象,通常很少有可以调用的有趣函数。
后期编辑:或者,可以为非托管功能编写 C 样式包装函数。您必须一次性传递所有参数(您可以传递结构),但您可以在标准 C/C++ 中编写包装器。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 尝试导入pybind-opencv模块时出现libgtk错误
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- 导入库可以跨dll版本工作吗
- C++将文本文件中的数据读取到结构数组中
- 如何将 C# 文本框输入与 C 结构和导入一起使用
- 导入C 功能将结构的指针返回到VB.NET中
- DLL导入纯虚拟结构和unique_ptr由于Compressed_pair而无法编译
- 是否可以使用 C# DllImport 从 DLL 导入非托管类或结构
- 如何从c++ dll中导入结构体?
- 导入结构参数