如何将结构中的char *从c#传递到c++

Posted

技术标签:

【中文标题】如何将结构中的char *从c#传递到c++【英文标题】:How to pass char* in struct from c# to c++ 【发布时间】: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。 【参考方案1】:

你的结构需要一个指向数组的指针;您正在编组数组。交易的一方期望获得地址“芝麻街 123 号”,而您提供的是该地址的公寓楼的精确复制品。那是行不通的。

要正确编组代码,您需要对 C# 中的内存管理有一个透彻和深入的了解。我的建议是您获得专家​​的服务。

【讨论】:

@FrankJ:完全正确。问题中没有足够的信息来给出可能是正确的答案,并且提出探索性问题以确定信息最好由对内存管理有透彻和深刻理解的专家来完成。如果你是这样的专家,那么我鼓励你给出一个你更喜欢的答案。【参考方案2】:

您可以尝试使用 StringBuilder 代替 byte[] 和 LPStr 代替 ByValArray:

public struct STATUSSTRUCT

    public UInt64 nameLen;
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 4128)]
    public StringBuilder name;


status = new STATUSSTRUCT();
status.nameLen = 4128;
status.name = new StringBuilder(4128);
getStatus(ref status);

https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype(v=vs.110).aspx

【讨论】:

以上是关于如何将结构中的char *从c#传递到c++的主要内容,如果未能解决你的问题,请参考以下文章

如何将结构数组从 c++ 传递到 c#?

如何将对象列表从 C++ 传递到 C#?

将 char*[] 从 c++ dll Struct 传递给 c#

将字节数组从 C# 传递到 C++ DLL 作为 char*

将结构数组从 C#(.NET Core) 传递到 C++(未管理)

将 char 数组值从 C++ 传递到 C# 应用程序