从c ++导入返回结构的函数

时间:2012-12-29 06:23:38

标签: c#

我的c ++应用程序中有这个结构:

struct Animation
{
    UINT To;
    UINT From;
    USHORT AnimationID;
};

struct Entity
{
    USHORT X, Y;
    UINT SERIAL;
    USHORT SpriteID;
    BYTE DIRECTION;
    USHORT TYPE;
    BOOL Cursed;
    BOOL Fased;
    BOOL IsPet;

    void AddAnimation(Animation &const  a)
    {
        Animations.push_back(a);
    }

    void ClearAnimations()
    {
        this->Animations.clear();
    }

private:
    vector<Animation> Animations;
};

我有这个导出功能:

extern "C" __declspec(dllexport) Entity GetNearest(void)
{
    Entity & result = GetNearestEntity();
    return result;
}

是否可以使用它并获取c#中的实体值?

我试着这样做:

  [DllImport("FatBoy.dll", SetLastError = true)]
        internal static extern Entity GetNearest();

        public struct Entity
        {
            ushort X, Y;
            uint SERIAL;
            ushort SpriteID;
            byte DIRECTION;
            ushort TYPE;
            bool Cursed;
            bool Fased;
            bool IsPet;
        }

当我打电话给我时,我收到错误:

Method's type signature is not PInvoke compatible.

1 个答案:

答案 0 :(得分:4)

C ++代码:

struct EntityValue
{
    USHORT X, Y;
    UINT SERIAL;
    USHORT SpriteID;
    BYTE DIRECTION;
    USHORT TYPE;
    BOOL Cursed;
    BOOL Fased;
    BOOL IsPet;
};

EntityValue* CopyValueOfEntity(Entity* source)
{
    EntityValue *result = new EntityValue();
    result->X = source->X;
    result->Y = source->Y;
    result->SERIAL = source->SERIAL;
    result->SpriteID = source->SpriteID;
    result->DIRECTION = source->DIRECTION;
    result->TYPE = source->TYPE;
    result->Cursed = source->Cursed;
    result->Fased = source->Fased;
    result->IsPet = source->IsPet;
    return result;
}

extern "C" __declspec(dllexport) EntityValue* GetNearest(void)
{
    Entity *result = GetNearestEntity();
    result->X = 1;
    result->Y = 2;
    result->SERIAL = 3;
    result->SpriteID = 4;
    result->DIRECTION = 5;
    result->TYPE = 6;
    result->Cursed = FALSE;
    result->Fased = FALSE;
    result->IsPet = FALSE;
    return CopyValueOfEntity(result);
}

C#代码:

class Program
{
    [DllImport("FatBoy.dll", SetLastError = true)]
    internal static extern IntPtr GetNearest();

    [StructLayout(LayoutKind.Sequential)]
    unsafe struct EntityValue
    {
        public ushort X, Y;
        public uint SERIAL;
        public ushort SpriteID;
        public byte DIRECTION;
        public ushort TYPE;
        public bool Cursed;
        public bool Fased;
        public bool IsPet;
    }

    static void Main(string[] args)
    {
        unsafe
        {
            EntityValue* data = (EntityValue*)GetNearest();

            Console.WriteLine(data->X);
            Console.WriteLine(data->Y);
            Console.WriteLine(data->SERIAL);
            Console.WriteLine(data->SpriteID);
            Console.WriteLine(data->DIRECTION);
            Console.WriteLine(data->TYPE);
            Console.WriteLine(data->Cursed);
            Console.WriteLine(data->Fased);
            Console.WriteLine(data->Fased);
        }
    }
}

结果如下:

Demonstrate

Integrating with Native DLLs会很有用。