English 中文(简体)
C# 中等量的字符数组
原标题:char[] array equivalent in c#

我有一个c++ 结构, 它有像下面一样的字符[ 20], 它被打包了 。

#pragma pack(push, temp_aion_packed, 1)
struct temp
{
  char x[20];
  char y[20];
};
#pragma pack(pop, temp_aion_packed)

现在,我怎么能在 C# 中写出这个支架, 这样两个都是一样的。 我已经在c# 中写了这样的话。

[DataContract]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1),Serializable]
public class temp
{
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
     public string x;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
     public string y;
}

下方是 c# 中的 pinvoke 声明

[DllImport("rmsCAPI.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true, EntryPoint = "OrderRequirement")]
    public static extern int OrderRequirement(ref temp tmp);

c++ 函数,调用此构造为参数

long __stdcall OrderRequirement(struct temp *tmp)
{
  string p="";
  string q="";
  p=temp->x;
  q=temp->y;
  char buff[2048];
  sprintf(buff,"p: %s
 q: %s
 x: %s
 y: %s
",p,q,temp->x,temp->y);
 }

但当我在 c# 中这样做的时候, 它给了我在 c++ 中的垃圾数据, 当我在 c# 中为他们指定值时。 任何人都能帮忙吗?

感谢大家的帮助, 上面的一个, 但现在我有一个新的问题, 这是这个问题的延伸, 我提供所有细节在下面。

我在 c++ 中的结构

#pragma pack(push, temp_aion_packed, 1)
struct temp
{
  long req;
  struct type m_type;
  short id;
  char x[20];
  char y[20];
};
#pragma pack(pop, temp_aion_packed)

#pragma pack(push, type_aion_packed, 1)
struct type
{
  short i;
};
#pragma pack(pop, type_aion_packed)

我写了等同的c# 支架像这样

[DataContract]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1),Serializable]
public struct temp
{
   [DataMember]
    public long req;
   [DataMember]
    [MarshalAs(UnmanagedType.Struct)]
     public type m_type;
   [DataMember]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
     public string x;
   [DataMember]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
     public string y;
}

[DataContract]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1),Serializable]
public struct type
{
  [DataMember]
    public short i;
}

下面就是我的C#pinvoke

[DllImport("rmsCAPI.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true, EntryPoint = "OrderRequirement")]
    public static extern int OrderRequirement(ref temp tmp);

下面是我的 c+++ 方法, 它调用 struct 作为参数

long __stdcall OrderRequirement(struct temp *tmp)
{
  char buff[2048];
  sprintf(buff,"req: %ld 
 id: %d 
 x: %s
",tmp->req,tmp->id,tmp->x);
}

现在我要面对的问题是, 我有结构变量 m_ type( strutct "type" ), 在结构温度中宣布, 之前宣布的变量( long req), 在我的 c++ 程序中打印精细, 但之后宣布的变量没有给我任何输出。 因此我认为 c# 中的结构声明混乱了, 我无法找到它, 任何人都能帮上忙 。

最佳回答

您在 C# 中将支架声明为类。 这很好, 但它意味着该类型的任何变量已经是一个引用。 所以您不需要通过 < code> ref 。 当您通过一个类时, 如果您通过该类, 最终会将一个指针传递到对象的指针上。 间接值是太多的 。

因此C#代码中的P/invoke应该是这样:

public static extern int OrderRequirement(temp tmp);

修正它的另一种方式是将 ref 留在函数声明中,但将 temp 类型声明为 struct ,而不是 class 。这是因为 struct 是一个值类型。其类型为支架的变量是一个值,而不是引用。

两种解决方案都有效,由你选择。


您的 C++ 代码中还有一个问题 。

sprintf(buff,"p: %s
 q: %s
 x: %s
 y: %s
",p,q,temp->x,temp->y);

您正在通过 p q , 它们是类型 std:: 字符串 printf , 并期望 格式字符串打印它们。 这是错误的。 您需要在字符串上调用 c_str () 。 例如 :

sprintf(
  buff,
  "p: %s
 q: %s
 x: %s
 y: %s
",
  p.c_str(),q.c_str(),temp->x,temp->y
);

您更新的问题在于 Windows C++ 中长32位元, C# 中长64位元。 您需要在 C# 中将其声明为 < code> int 。 您完全错过了 < code> id 字段 。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1),Serializable]
public struct temp
{
    [DataMember]
    public int req;

    [DataMember]
    public type m_type;

    [DataMember]
    public short id;

    [DataMember]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string x;

    [DataMember]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string y;
}
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...