我正在开发一个新的C#程序的技术问题。 在这个项目中,我需要在TCP / IP网络上与另一个没有基于Windows的系统进行通信。 Al在另一个系统上编写的软件是用C语言完成的,任何其他未来的开发都将在C / C ++中完成。 这些协议都是由另一位工程师在C中完成的,协议的定义都是使用C typedef struct定义所有变量并使用memcpy提取/放置对C有效的数据包来完成的。 我的所有协议都作为C头文件提供,其中包含所有typedef和struct,并且将来对协议所做的任何更改都将以相同的方式完成。
我的问题是,如果有任何方法可以在C#中使用它们吗?
我已经尝试将它们作为一个类编译成一个DLL库而不能正常工作,因为C#只能使用托管的C dll。如果我尝试编译为托管C类,由于协议中有许多数组,并且因为C代码必须符合一系列的工厂规范,因此许多变量都是typedef,这只会变得一团糟。 d。现在我可以去重做C#中的所有结构,但这需要花费很多时间,每次进行更改或添加到协议中时,我都必须重做它。甚至没有提到我每次都会出现错误滑倒的危险。
如何使用我的C项目是另一位工程师只会向我提供更新的头文件。
那么有没有办法直接在C#中使用这些头文件或者每次更新协议时我都可以进行自动转换? 好吧,我基本上需要使用这个头文件从TCP / IP连接的数据流中提取数据(无需开始使用memcpy)
使用C#的原因是因为我在WPF中使用了大量图形而Visual C ++不支持WPF
非常感谢任何帮助或建议?
答案 0 :(得分:1)
我曾经不得不在C#中使用C头来获取通过TCP / IP发送的编组结构的定义。我们使用的方法是通过T4文本模板解析头文件。这是一个有点冗长的任务,你必须为你的标题编写足够好的C解析器并使用它来生成.cs文件,所以有很多字符串混乱。对我们来说,这是一个很好的解决方案,所以它也可以帮到你。
在这里查看T4:http://msdn.microsoft.com/en-us/library/bb126445.aspx
答案 1 :(得分:1)
不是一个真正的答案,更像是一个可能的好解决方案:
创建一个包含C头文件中现在信息的defintion文件。然后使用它来生成.h标头和合适的C#源代码。
如果数据相当简单,那么也可以使用简单的键值文件格式,甚至是csv文件。但如果它更复杂,那么最好使用XML,这样可以更简单地以编程方式解析。
如果对具有与语言无关的定义文件存在阻力,那么您可以尝试使.c头文件遵循一些字符串格式化规则,因此您可以简单地解析它并从中生成C#代码(只需确保编写.h的人知道,它不再是C,它实际上是你自己的C语言定义语言,任何额外的C东西都必须转到另一个文件。)
答案 2 :(得分:0)
你不能也不能在C#中使用头文件你需要将它编译成dll并从c#
在c文件中,您需要定义#define DLLAPI __declspec(dllexport)
并定义类似以下DLLAPI *return-value-data-type function-name*
的方法
从c#中你需要像下面那样调用它
[DllImport(@"*dll-path*")]
public static extern *return-value-datatype function-name*
如果需要,您可以对数据类型进行编组,如下所示
[DllImport(@"*dll-path*")]
public static extern void InitParam([MarshalAs(UnmanagedType.LPWStr)] string inputFile,
[MarshalAs(UnmanagedType.LPWStr)] string outputFile,
[MarshalAs(UnmanagedType.LPWStr)] string templateFile,
[MarshalAs(UnmanagedType.LPWStr)] string userName,
[MarshalAs(UnmanagedType.LPWStr)] string manifestFilePath,
[MarshalAs(UnmanagedType.LPWStr)] string usersRightList);
[DllImport(@"*dll-path*")]
public static extern Int32 ProtectDocument(
[MarshalAs(UnmanagedType.LPStr)]string validToDate);
[DllImport(@"*dll-path*")]
public static extern void DebugGeneratedFiles(
[MarshalAs(UnmanagedType.LPWStr)] string singedIssuenceLicenseFilePath,
[MarshalAs(UnmanagedType.LPWStr)] string encryptedContentOutputFilePath);