C++整数& C# 中的长编组

发布于 2024-10-09 08:21:33 字数 923 浏览 3 评论 0原文

我目前正在将专有 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 的 tLONGtINT 本身是相同的(至少对于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南汐寒笙箫 2024-10-16 08:21:33

尝试将其编组为 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.

喵星人汪星人 2024-10-16 08:21:33

它是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.

短叹 2024-10-16 08:21:33

这是良好的类型对应列表。

在 C# 中,指针类型通常为 IntPtr

Here is good list of type correspondence.

For pointer types is usually IntPtr in C#.

格子衫的從容 2024-10-16 08:21:33

如果我没记错的话 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 and void* on C/C++ side.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文