【发布时间】:2016-08-25 20:16:43
【问题描述】:
感觉我的问题和this差不多。
到目前为止,我有一个用 C++ 定义的结构,如下所示:
typedef struct struct_type1
{
uint64 nameLen;
char * name;
} STATUSSTRUCT;
和一个函数定义为:
extern int _stdcall getStatus(STATUSSTRUCT * status);
大概是这样的功能:
int _stdcall getStatus(STATUSSTRUCT * status)
{
status->nameLen = someLength;
status->name = someName;
return 1;
}
请注意,我实际上无法更改 C++ 代码(由于各种原因)或头文件。
我的 C# 代码如下所示:
public struct STATUSSTRUCT
{
public UInt64 nameLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4128)]
public byte[] name;
}
STATUSSTRUCT status;
[DllImport("test.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int getStatus(ref STATUSSTRUCT status);
public void refreshStatus() {
status = new STATUSSTRUCT();
status.nameLen = 4128;
status.name = new byte[4128];
getStatus(ref status);
}
但是,调用 refreshStatus 会给我 System.AccessViolationException。
谁能帮我弄清楚如何在 C++ 中从 C# 调用这个函数?
【问题讨论】:
-
C# 不是垃圾收集语言吗?如果是这样,如果
name是由 C# 收集的垃圾怎么办?C结构name将指向什么?您可能需要做的(这已经够糟糕了)是让您的 C++ 代码分配内存,然后将数据复制到name,而不仅仅是存储指针。 -
如果您的问题与指针有关,您可以在项目属性中允许不安全代码,这样您就可以在 C# 中使用指针(在 C# 中定义 Char*)
-
@PaulMcKenzie:“C# 不是垃圾收集语言吗?” - 是的。就像 C++ 一样。两种语言都不会自动销毁对象,尽管它们仍在使用中。然而,一个显着的区别是,.NET 有一个压缩堆,并且对象可以在其生命周期内在内存中移动。为避免这种情况(将结构传递给非托管代码时),您可以使用 fixed 关键字,或使用句柄类型
Pinned调用 GCHandle.Alloc。
标签: c# c++ visual-studio