Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.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#DLL+;代码-p/调用-更改值_C#_C++_.net_Visual Studio 2015_Pinvoke - Fatal编程技术网

C+中的C#DLL+;代码-p/调用-更改值

C+中的C#DLL+;代码-p/调用-更改值,c#,c++,.net,visual-studio-2015,pinvoke,C#,C++,.net,Visual Studio 2015,Pinvoke,我有一个C#DLL,它使用了很多“常用”DLL。现在我想从C++程序中调用这些函数/方法。 在C代码中,我有这样一个结构 [StructLayout(LayoutKind.Sequential)] 公共结构测试 { 公共字符串MyTestString; 公共整数; } 和一名代表 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 公共委托无效回拨委托(测试t); 它正在具有“回调”的类中使用 在C++/CLI代码中,我也得到了“相同”的结

我有一个C#DLL,它使用了很多“常用”DLL。现在我想从C++程序中调用这些函数/方法。 在C代码中,我有这样一个结构

[StructLayout(LayoutKind.Sequential)]
公共结构测试
{
公共字符串MyTestString;
公共整数;
}
和一名代表

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
公共委托无效回拨委托(测试t);
它正在具有“回调”的类中使用

在C++/CLI代码中,我也得到了“相同”的结构。(C++项目是Unicode)

struct测试
{
char*MyTestString;
int-MyInteger;
};
我导出使用过的函数来访问C代码

在函数中,我实例化了C#类的一个对象,并将委托作为
IntPtr

IntPtr ptr = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(csharp->GetDelegate());
之后,我调用函数并将结构的一个对象作为参数传递

//typedef void(*NativeToManaged)(Test t);
NativeToManaged funcPtr = static_cast<NativeToManaged>(ptr.ToPointer());
funcPtr(t);
//typedef void(*NativeToManaged)(测试t);
NativeToManaged funcPtr=静态_转换(ptr.ToPointer());
funcPtr(t);
在非托管代码中,我为char*分配内存,并复制/分配一个字符串<代码>“正在发生什么”作为示例。(使用C++/CLI标头)


现在开始解决问题:

我正确地接收了C代码中的结构,虽然试图设置字符串或修改C边上的整数不会改变C++侧的任何东西——我假设结构只是被复制,尽管我不知道如何通过对C代码的引用。(可能作为指针或参考?)


由于这是我第一次这样做,是否有人碰巧知道问题所在?C#代码应该正确接收字符串和其他值,并能够修改它们。我至今还没有找到谷歌上的解决方案,这里。

这是C++ + CLI而不是C++。停止使用p/invoke并添加对C#程序集的引用。您正在按值传递结构,这使得无法更新本机结构。必须声明参数
[In,Out]ref Test t
。必须使用
Test*t
相应地更改本机代码。字符串是一个很大的内存管理问题,您可以将其声明为IntPtr,但这很容易损坏和泄漏内存。唯一安全的方法是在DavidHeffernan代码中声明BSTR。@你能解释一下,这是如何用非托管C++代码工作的?正如我在我的问题中看到的,这是一个例子,我有非托管C++代码,并且希望调用C语言的DLL。如果我可以添加对非托管代码的引用,我会这样做。@HansPassant我已经更改了代理签名,将
[In,Out]ref Test t
作为参数,并将结构的字符串更改为
BSTR
。谢谢你。尽管我仍然不确定如何将结构正确地传递给C代码。目前,我声明了一个变量
Test
,并将其作为
Test*
(&t)传递给C#委托。这是正确的吗?看来,C++代码堆在每次运行时都被破坏了<代码>。你有C++、C++、CLI和C++吗?我以为这只是C#和C++/CLI。
IntPtr ptr = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(csharp->GetDelegate());
//typedef void(*NativeToManaged)(Test t);
NativeToManaged funcPtr = static_cast<NativeToManaged>(ptr.ToPointer());
funcPtr(t);