C++整数& C# 中的长编组
我目前正在将专有 dll(API)移植到 C#,在编组某些使用的数据类型时遇到一些问题。
例如,API 头文件定义了以下类型:
typedef unsigned int tINT; /* natural unsigned */
typedef signed int tINTs; /* natural signed */
typedef unsigned int tLONG; /* 32 bit unsigned */
typedef unsigned long tPTR; /* 32/64-bit pointer */
然后我有以下函数定义:
tINTs SomeApiFunction ( const tPTR hdl, tINT param );
我通常直接使用 C# 的 int
(Int32
),或未签名的版本。 API 的 tLONG
和 tINT
本身是相同的(至少对于 API 而言)。但我不确定tPTR
。我现在在 C# 中将其设为 uint
,因为它是 32 位 int,但我不确定 long
在 64 位计算机上的行为如何。
我需要做什么才能确保 API 在 32 位和 64 位机器上都能正常工作?
这就是我现在要做的:
[DllImport( "api.dll" )]
public static extern int SomeApiFunction ( uint hdl, uint param );
遗憾的是 API 并没有很好的文档记录,因此我不确定所有这些(重叠的)typedef 的意图是什么。除了我上面包含的标题注释之外,没有有关实际类型的信息。
I'm currently porting a proprietary dll (an API) to C#, and I have some problems when marshalling some of the used data types.
For example the API header file defines the following types:
typedef unsigned int tINT; /* natural unsigned */
typedef signed int tINTs; /* natural signed */
typedef unsigned int tLONG; /* 32 bit unsigned */
typedef unsigned long tPTR; /* 32/64-bit pointer */
Then I for example have the following function definition:
tINTs SomeApiFunction ( const tPTR hdl, tINT param );
I'm usually marshalling the int
directly with C#'s int
(Int32
), or the unsigned version. The API's tLONG
and tINT
are as such the same (at least for the API). But I'm not sure with the tPTR
. I have now made it a uint
in C#, because it is a 32bit int, but I'm not sure how the long
would behave on a 64bit machine.
What do I have to do to make sure that the API will work on both 32bit and 64bit machines correctly?
This is what I would have done now:
[DllImport( "api.dll" )]
public static extern int SomeApiFunction ( uint hdl, uint param );
Sadly the API is not really well documented, as such I am not sure what the intention was with all those (overlapping) typedefs. Apart from the header comments I have included above there is no information about the actual types.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试将其编组为
IntPtr
。在.Net中,IntPtr在32位系统上为4字节,在64位系统上为8字节。Try to Marshal it as an
IntPtr
. IntPtr is 4 bytes on a 32bit system and 8 bytes on a 64bit system in .Net.它是C/C++编译器的实现细节。您应该按照注释声明它 IntPtr。如果代码是由 MSVC 编译器编译的,那么它就不能在 64 位模式下工作,它会长期使用 32 位。不足以存储指针。
It is an implementation detail of the C/C++ compiler. You should go by the comment and declare it IntPtr. If the code is compiled by the MSVC compiler then it isn't going to work in 64-bit mode, it uses 32-bits for a long. Not enough to store a pointer.
这是良好的类型对应列表。
在 C# 中,指针类型通常为
IntPtr
。Here is good list of type correspondence.
For pointer types is usually
IntPtr
in C#.如果我没记错的话
int
uint
和其他基本类型是底层 Windows API 的正确类型。然而,对于指针,最好在 C# 端使用
IntPtr
,在 C/C++ 端使用void*
。If I remember correctly
int
uint
and other primitive types are the right type for the underlying windows API.For pointers however, its best to use
IntPtr
on C# side andvoid*
on C/C++ side.