从非托管C++;到C#

从非托管C++;到C#,c#,c++,unmanaged,C#,C++,Unmanaged,注意:最终工作解决方案在编辑之后 我希望有人能帮我解决过去几天我一直想解决的问题 我试图把一个结构从非托管C++ DLL传递到一个C脚本。这就是我到目前为止所做的: C++ C# 问题是这是可行的,但打印的值完全关闭(有时打印大约400,有时打印最大int值) 我猜我在C#中封送结构的方式有问题。有什么想法吗 编辑: 这是使用ref的工作解决方案: C++ C# MarkerInfo变量是局部变量,当函数返回时,该变量超出范围。 不要返回指向局部变量的指针,它们指向的对象将不再存在。您返回的是指

注意:最终工作解决方案在编辑之后

我希望有人能帮我解决过去几天我一直想解决的问题

我试图把一个结构从非托管C++ DLL传递到一个C脚本。这就是我到目前为止所做的:

C++

C#

问题是这是可行的,但打印的值完全关闭(有时打印大约400,有时打印最大int值)

我猜我在C#中封送结构的方式有问题。有什么想法吗

编辑:

这是使用ref的工作解决方案:

C++

C#

MarkerInfo变量是局部变量,当函数返回时,该变量超出范围。
不要返回指向局部变量的指针,它们指向的对象将不再存在。

您返回的是指向一个局部变量的指针,该变量在.NET读取之前已经被销毁。这是纯C++的坏主意,P/Unjk./P>是个坏主意。

相反,让C传递一个指向结构的指针(只使用<代码> REF关键字),C++代码就填入其中。

将要给出这个旋转…谢谢你的邮件

// 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);
// */
//要返回的项的新结构和泛型返回
结构_itemStruct
{
unsigned int id;//默认情况下为0,因此所有列表都应该从1开始,0表示未分配
wchar_t*名称;
};
//对于DLL库,请在void之前添加以下内容。。。
//出口空气污染指数
void getItems(标准::向量*项)
{
//在此处设置项目列表值
//unsigned char*bytePtr=(unsigned char*)&items;//手动指针返回
返回;
};
/*//理论上,c#代码将是。。。
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi,Pack=1)]
公共结构_itemStruct
{
公共无符号整数Id;
公共字符串名称;
}
[DllImport(“ListOfItems”)]//用于ListOfItems.DLL
公共静态外部无效getItems(
[Marshallas(UnmanagedType.Struct)]参考列表项;
// */

谢谢!你对我应该怎么做有什么建议吗?我已经尝试使用ref,但仍然没有得到正确的值。。。你能看看我编辑过的问题吗?@kolarek:就像我在回答中说的,当你使用
ref
out
关键字C时,实际上会传递一个指针。因此,在C++侧使用空侦探标记(/*./MaqeStReT**)< /C> >,然后<代码> MARERIVENP> > ID=3;<代码>。此外,在p/Unjk签名中去掉属性中的<代码>,这意味着不从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);
struct markerStruct {
    int id;
};

...

EXPORT_API void detectMarkers( ... , markerStruct *MarkerInfo) {
    MarkerInfo->id = 3;
    return;
}
[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 );
// 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);
// */