9

注:最終的な作業ソリューションは編集後です!

ここ数日間解決しようとしていた問題を誰かが助けてくれることを願っています。

アンマネージ C++ DLL から C# スクリプトに構造体を渡そうとしています。これは私がこれまでに持っているものです:

C++

EXPORT_API uchar *detectMarkers(...) {
    struct markerStruct {
            int id;
    } MarkerInfo;

    uchar *bytePtr = (uchar*) &MarkerInfo;

    ...

    MarkerInfo.id = 3;
    return bytePtr;
}

C#

[DllImport ("UnmanagedDll")] 
    public static extern byte[] detectMarkers(...);

...

[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 1)]
public struct markerStruct
{
    [MarshalAs(UnmanagedType.U4)]
    [FieldOffset(0)]
    public int Id;
}

...

markerStruct ByteArrayToNewStuff(byte[] bytes){
    GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    markerStruct stuff = (markerStruct)Marshal.PtrToStructure(
        handle.AddrOfPinnedObject(), typeof(markerStruct));
    handle.Free();
    return stuff;
}

...

print(ByteArrayToNewStuff (detectMarkers(d, W, H, d.Length) ).Id);

問題は、これが機能することですが、出力される値が完全にオフになっていることです (400 前後で出力されることもあれば、最大 int 値が出力されることもあります)。

C# で構造体をマーシャリングした方法に何か問題があると思います。何か案は?

編集:

これはrefを使用した実用的なソリューションです:

C++

struct markerStruct {
    int id;
};

...

EXPORT_API void detectMarkers( ... , markerStruct *MarkerInfo) {
    MarkerInfo->id = 3;
    return;
}

C#

[DllImport ("ArucoUnity")] 
    public static extern void detectMarkers( ... ,
        [MarshalAs(UnmanagedType.Struct)] ref MarkerStruct markerStruct);

...

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct MarkerStruct
{
    public int Id;
}

...

detectMarkers (d, W, H, d.Length, ref markerInfo);      
print( markerInfo.Id );
4

3 に答える 3

0

これに旋風を巻き起こすつもりです...投稿のthx...

// new struct and generic return for items to 
struct  _itemStruct
{
    unsigned int id; // 0 by default, so all lists should start at 1, 0 means unassigned
    wchar_t *Name;
};

// for DLL lib precede void with the following... 
// EXPORT_API 
void getItems(std::vector<_itemStruct *> *items)
{
    // set item list values here


    //unsigned char *bytePtr = (unsigned char*)&items; // manual pointer return

    return;
};

/* // In theory c# code will be...
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct _itemStruct
{
    public unsigned int Id;
    public string Name;
}

[DllImport ("ListOfItems")] // for ListOfItems.DLL
public static extern void getItems(
[MarshalAs(UnmanagedType.Struct)] ref List<_itemStruct> items);
// */
于 2016-04-15T15:14:00.110 に答える