Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.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++ DLL,它有一个C风格导出函数,我想从C代码中使用。该函数应该将数组作为参数并对其进行修改,以便我可以在C#中使用结果_C#_C++_Arrays_Dll - Fatal编程技术网

如何在c+中修改c#数组+;动态链接库 我有一个非托管C++ DLL,它有一个C风格导出函数,我想从C代码中使用。该函数应该将数组作为参数并对其进行修改,以便我可以在C#中使用结果

如何在c+中修改c#数组+;动态链接库 我有一个非托管C++ DLL,它有一个C风格导出函数,我想从C代码中使用。该函数应该将数组作为参数并对其进行修改,以便我可以在C#中使用结果,c#,c++,arrays,dll,C#,C++,Arrays,Dll,所以我想出了如何使用浮点数组来实现这一点。当我的C函数如下所示时 __declspec( dllexport ) float testArrayFlt( const float *f, int arraySize, float *fCopy ) { float sum = 0.0f; for( int i = 0; i < arraySize; i++ ) { sum += f[i]; fCopy[i] = f[i]; }

所以我想出了如何使用浮点数组来实现这一点。当我的C函数如下所示时

__declspec( dllexport ) float testArrayFlt( const float *f, int arraySize, float *fCopy )
{
    float sum = 0.0f;

    for( int i = 0; i < arraySize; i++ )
    {
        sum += f[i];
        fCopy[i] = f[i];
    }

    return sum;
}
现在,当我这样使用它时,一切都很好:

float[] flt = new float[10];
float[] fltCopy = new float[flt.Length];
for( int i = 0; i < flt.Length; i++ )
    flt[i] = i;

float f = testArrayFlt( flt, flt.Length, fltCopy );

Console.WriteLine( "flt sum: " + f );
for( int i = 0; i < fltCopy.Length; i++ )
    Console.WriteLine( "flt #" + i + ": " + fltCopy[i] );
…将dll导入声明为

[DllImport( lib )]
public static extern Vec3f testArrayVec3( Vec3f[] points, int arraySize, Vec3f[] pointsCopy );
…并按如下方式使用它:

__declspec(dllexport) glm::vec3 testArrayVec3( const glm::vec3 *points, int arraySize, glm::vec3 *pointsCopy )
{
    glm::vec3 sum( 0.0f );

    for( int i = 0; i < arraySize; i++ )
    {
        sum += points[i];
        pointsCopy[i] = points[i];
    }

    return sum;
}
Vec3f[] points = new Vec3f[10];
Vec3f[] pointsCopy = new Vec3f[points.Length];
for( int i = 0; i < points.Length; i++ )
    points[i].X = points[i].Y = points[i].Z = i;

Vec3f p = testArrayVec3( points, points.Length, pointsCopy );

Console.WriteLine( "vec sum: " + p );
for( int i = 0; i < pointsCopy.Length; i++ )
    Console.WriteLine( "vec #" + i + ": " + pointsCopy[i] );
Vec3f[]点=新的Vec3f[10];
Vec3f[]点透视=新的Vec3f[points.Length];
对于(int i=0;i
现在我得到以下输出:

向量总和:[45,45,45]

向量0:[0,0,0]

向量1:[0,0,0]

向量2:[0,0,0]

向量3:[0,0,0]

向量4:[0,0,0]

向量5:[0,0,0]

向量6:[0,0,0]

向量7:[0,0,0]

向量8:[0,0,0]

向量9:[0,0,0]

让我困惑的是,这离正确不远,因为总和的计算和返回确实有效。看起来第二个数组没有通过引用正确地传递,但是我不知道怎么做。另外,在浮动版本中,它的工作原理就是这样。我还检查了dll,glm::vec3赋值确实有效,因此PointScope实际上在循环后包含正确的数据,但它没有到达C端


有任何想法吗?

你是否尝试过在C语言中使用不安全的块,并将数组作为指针指向C++ DLL?你说得对,它确实适用于不安全代码。谢谢不过还是很奇怪。我现在可以接受这一点,但最终,我更喜欢没有不安全代码的解决方案。我的意思是,它应该像这样工作,不是吗?“它应该像这样工作,不是吗?”-不,显然不是。在C++中,对象的地址在对象的生命周期内不可更改。在.NET中,这种情况经常发生。那么为什么要这样做呢?无论如何,如果需要与非托管代码进行互操作,请使用C++/CLI。可能存在多个问题,首先,这些值没有固定在内存中,这意味着它们的位置发生了更改。有时它可能会工作,但当垃圾收集器经过时,您使用的是无效指针。另一个问题是C++中的数组与C++中的数组没有任何关系,例如它包含关于它的大小的信息,它也存储在某个内存中。二进制布局不兼容。这里重要的是pinvoke marshaller是否认为参数是可blittable的。如果是,那么它可以简单地固定数组并传递指针,您的C代码将直接写入托管对象。显然没有,我不知道为什么。然后必须明确表示希望将数组内容复制回来。使用
[In,Out]Vec3f[]pointscope
。使用
fixed
是一种击败封送员的黑客手段,但它相当危险,GC堆损坏是一个你将要寻找一个月的bug。
[DllImport( lib )]
public static extern Vec3f testArrayVec3( Vec3f[] points, int arraySize, Vec3f[] pointsCopy );
Vec3f[] points = new Vec3f[10];
Vec3f[] pointsCopy = new Vec3f[points.Length];
for( int i = 0; i < points.Length; i++ )
    points[i].X = points[i].Y = points[i].Z = i;

Vec3f p = testArrayVec3( points, points.Length, pointsCopy );

Console.WriteLine( "vec sum: " + p );
for( int i = 0; i < pointsCopy.Length; i++ )
    Console.WriteLine( "vec #" + i + ": " + pointsCopy[i] );