我正在开发一个C#应用程序.由于我有一些适用于C/C++的最小二乘拟合算法太过繁琐,我已经将C++代码变成了一个dll,然后在C#中创建了一个包装器.
在C#代码中,我定义了一个结构,该结构作为指针传递给非托管C++代码.该结构包含拟合函数的初始猜测值,它还用于返回拟合的结果.
在我看来,您必须在托管代码和非托管代码中定义结构.但是,将来使用我的源代码的人可能决定更改C#应用程序中结构的字段,而不了解他们还必须更改本机代码中的结构.这最多会导致运行时错误(并且会导致错误的结果),但是没有错误消息告诉开发人员/最终用户有什么问题.
根据我的理解,不可能在非托管C++ DLL中创建一个测试,检查结构是否包含正确的字段,但是可以让DLL将正确格式的结构返回给C#包装器吗?
否则,有哪些方法可以降低未来一些粗心的程序员导致难以检测的运行时错误的风险?
示例代码:
//C++
struct InputOutputStruct {
double a,b,c;
}
extern "C" __declspec(dllexport) void DoSomethingToStruct(InputOutputStruct* s)
{
Run Code Online (Sandbox Code Playgroud)
// ...算法
}
//C#
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct InputOutputStruct {
public double a,b,c;
}
[DllImport("CpluplusDll.dll")]
public static unsafe extern bool DoSomethingToStruct(InputOutputStruct* s);
class CSharpWrapper {
static void Main(string[] args)
{
InputOutputStruct s = new InputOutputStruct();
unsafe {
InputOutpustruct* sPtr = &s;
DoSomethingToStruct(sPtr);
s = *sPtr;
}
}
}
Run Code Online (Sandbox Code Playgroud) 我发现自己无法解释为什么以下代码有效.不用说,我对C++很陌生......
#include <cstdio>
void foo(char* p)
{
p[0] = 'y';
}
int main()
{
char a[1];
a[0] = 'x';
printf("a[0] = %c\n", a[0]);
foo(a);
printf("a[0] = %c\n", a[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该计划输出
a[0] = x
a[0] = y
Run Code Online (Sandbox Code Playgroud)
是什么让我感兴趣的是我没有将指针传递给foo.那么如何才能改变数组的值?这只适用于char数组吗?
char和char [1]之间差异的答案证实了我的观察,但它没有详细说明为什么会出现这种情况.
谢谢!