c# - 是否可以使用 C# DllImport 从 DLL 导入非托管类或结构?

标签 c# c++ class dll dllimport

作为 msdn http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx说“平台调用服务 (PInvoke) 允许托管代码调用在 DLL 中实现的非托管函数。”

我想从我用 C++ 制作的 DLL 中导入一些类
这可能吗?

例如,我在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) 基本类型,如 double、int32 等,可以高效地跨 P/Invoke 层移动 - 更复杂的类型可以让你获得 .net 的 thunking 变体 - msft doco 涵盖了哪些数据类型可以高效地移动,尝试并使用它们

3) C++ 领域中的指针在 .net 领域中都是 IntPtr,如果你想安全起见,你应该将其视为句柄,即你让 C++ 端对底层结构进行任何操作/访问

4) 访问原生 C++ 非常简单(Handle Prop 是 IntPtr,最初来源于原生 C++ 端)

[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# - 是否可以使用 C# DllImport 从 DLL 导入非托管类或结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10871733/

相关文章:

c# - Swagger-Codegen 自定义设置

c++ - string::find 问题 (C++)

Java:如何从泛型类型中获取类文字?

c++ - 命名通过引用设置参数的函数的样式?

C++ NetBeans std::array 不可用

CSS 选择器选择具有此 id 和此类的元素

c# - C#中的父子继承管理

c# - LINQ 和 SQL 中看似等效的查询返回不同的结果

c# - .net core rc2 非平凡集成测试不起作用

c# - Crittercism 崩溃报告未交付