我可以在C#中使用C头作为协议吗
Can I use C headers for protocol in C#
我在开发一个新的C#程序时遇到了技术问题。在这个项目中,我需要在TCP/IP网络上与另一个基于非windows的系统进行通信。所有在其他系统上编写的软件都是用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
如果有任何帮助或建议,我们将不胜感激?
我曾经不得不在C#中使用C头来获得通过TCP/IP发送的编组结构的定义。我们使用的方法是通过T4文本模板解析头文件。不过,这是一项有点长的任务,您必须为您的头编写足够好的C解析器,并使用它来生成.cs文件,所以有很多字符串混乱。对我们来说,这是一个足够好的解决方案,所以它也可能对您有所帮助。
请在此处查看T4:http://msdn.microsoft.com/en-us/library/bb126445.aspx
不是一个真正的答案,更像是一个可能的好解决方案:
创建一个定义文件,其中包含C头文件中的信息。然后使用它生成.h头和合适的C#源代码。
如果数据相当简单,那么也可以使用简单的键值文件格式,甚至csv文件。但是,如果它更复杂,那么最好使用XML,它更容易通过编程进行解析。
如果有一个独立于语言的定义文件存在阻力,那么你可以尝试让.c头文件遵循一些字符串格式规则,这样你就可以简单地解析它并从中生成c#代码(只需确保编写.h的人明白,它不再是c,它实际上是你自己的类c定义语言,任何额外的c内容都必须转到另一个文件)。
您不能也不能在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);
- 函数向量_指针有不同的原型,我可以构建一个吗
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 为什么我可以通过引用修改常量返回
- 我可以在 C++ 中的函数体之外进行操作吗?
- 我可以重新分配/覆盖std::字符串吗
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么我可以使用比分配的内存更多的内存
- 在一个读写器队列中,我可以用volatile替换原子吗
- 我可以把基础班提升为儿童班吗
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 我可以使用什么来停止循环而不是"返回 0"?
- 我可以使用反向迭代器作为ForwardIt吗
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 我可以在C#中使用C头作为协议吗
- 我可以用C++从协议缓冲区序列化/反序列化JSON吗