Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C+;从双指针结构封送字符*+;到C# 目标:从C++中检索结构数组,从C++侧完成,返回指针到Stutt指针(双指针)(不在我的控件中)。< /P> 样本C++代码: struct Output { char* Name; }; extern "C" { __declspec(dllexport) Output** getoutput() { Output* items = (Output*)malloc(sizeof(Output) * 4); items->Name = "Hello World"; return &items; } }_C#_C++_C - Fatal编程技术网

从C+;从双指针结构封送字符*+;到C# 目标:从C++中检索结构数组,从C++侧完成,返回指针到Stutt指针(双指针)(不在我的控件中)。< /P> 样本C++代码: struct Output { char* Name; }; extern "C" { __declspec(dllexport) Output** getoutput() { Output* items = (Output*)malloc(sizeof(Output) * 4); items->Name = "Hello World"; return &items; } }

从C+;从双指针结构封送字符*+;到C# 目标:从C++中检索结构数组,从C++侧完成,返回指针到Stutt指针(双指针)(不在我的控件中)。< /P> 样本C++代码: struct Output { char* Name; }; extern "C" { __declspec(dllexport) Output** getoutput() { Output* items = (Output*)malloc(sizeof(Output) * 4); items->Name = "Hello World"; return &items; } },c#,c++,c,C#,C++,C,c#侧码: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct Output { [MarshalAsAttribute(UnmanagedType.LPStr)] public string Name; }; [DllImport(@"CPPInvokeExposed.dll", CallingConvention =

c#侧码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Output
    {
        [MarshalAsAttribute(UnmanagedType.LPStr)]
        public string Name;
    };


 [DllImport(@"CPPInvokeExposed.dll",
       CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr getoutput();
static void Main(string[] args)
    {
       var output = Program.getoutput();
        Output[] outputs = new Output[1];
        MarshalUnmananagedArray2Struct<Output>(output, 1, out outputs);
        **outputs[0]// this has junk chars** 

    }

 public static void MarshalUnmananagedArray2Struct<T>(IntPtr unmanagedArray, int length, out T[] mangagedArray)
    {
        var size = Marshal.SizeOf(typeof(T));
        mangagedArray = new T[length];

        for (int i = 0; i < length; i++)
        {
            IntPtr ins = new IntPtr(unmanagedArray.ToInt64() + i * size);

            mangagedArray[i] = Marshal.PtrToStructure<T>(ins);
        }
    }
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
公共结构输出
{
[MarshalAsAttribute(UnmanagedType.LPStr)]
公共字符串名称;
};
[DllImport(@“cppInvokeeExposed.dll”),
CallingConvention=CallingConvention.Cdecl)]
公共静态外部IntPtr getoutput();
静态void Main(字符串[]参数)
{
var output=Program.getoutput();
输出[]输出=新输出[1];
MarshallUnmaNageDarray2Struct(输出,1,输出);
**输出[0]//这有垃圾字符**
}
public static void marshallUnmanageDarray2struct(IntPtr unmanagedArray,int length,out T[]manageDarray)
{
var size=Marshal.SizeOf(typeof(T));
mangagedArray=新的T[长度];
for(int i=0;i

不清楚问题是C++还是C代码。正确的方法是从结构中存在的C++获得char *。p> <一个奇怪的事情是,对于同一代码,如果C++代码返回单个指针(输出*)而不是双指针(输出**),则没有垃圾字符,得到正确的赋值。当从C++返回双指针时,好像有什么不对。


< P> C++代码导致不明确行为:

return&items

这将返回自动变量的地址。 当函数返回时,该变量将不再存在。访问该内存位置是非法的,会导致未定义的行为

一个干净的解决方案是返回指针本身,而不是地址。但在您的问题中,您声明返回类型不在您的控制之下

在这种情况下,您必须自己创建第二级间接寻址:

__declspec(dllexport) Output** getoutput()
{
    Output* items = (Output*)malloc(sizeof(Output) * 4);
    items->Name = "Hello World";

    Output **retval = (Output**)malloc(sizeof(Output*))
    *retval = items;
    return retval;
}
当然,您还需要注意在以后释放两个级别的内存分配

顺便说一句:
为4个结构分配内存,但只为第一个元素的成员分配一个值。

return&items返回自动变量的地址。当函数返回时,该变量将不再存在。访问该内存位置是非法的,会导致未定义的行为。相反,返回
就可以了。只需确保分配内存的方式在C#side(,)上有相应的deallocator即可。@GSerg pszReturn=(char*)::CoTaskMemAlloc(ulSize);即使如此,同样的(垃圾字符)问题仍然存在。@Gerhardh因为返回您提到的&items而得到编译器错误,但我没有找到任何方法来解决这个问题。解决这个问题的方法是返回
items
,而不是
&items
。更好的方法是将
items
作为out参数传递,并与告诉大小的
int*
参数一起传递,这样就可以在not之上进行自动编组。在生产中,我分配n个数字并填充所有数据,例如,我设置为first element。我尝试了一级间接寻址,但没有更改c#代码。垃圾问题依然存在。