如何在C#中用未知结构P/调用函数?

如何在C#中用未知结构P/调用函数?,c#,c++,c,C#,C++,C,我知道这听起来很奇怪,但我甚至不知道如何正确地问这个问题。我一直在尝试P/Invoke到NVidia的NVML库中,但成功率有限:我设法调用了该库导出的一些API 现在我正试图调用nvmlDeviceGetHandleByIndex\u v2,但我已经在这个问题上耽搁了很长时间。它接受一个nvmlDevice\u t指针,但我没有发现nvmlDevice\u t实际上超出了这一点: 问题是头文件没有对nvmlDevice\u st进行任何其他引用,因此我不知道要为它分配多少堆空间(如果有的话)。

我知道这听起来很奇怪,但我甚至不知道如何正确地问这个问题。我一直在尝试P/Invoke到NVidia的NVML库中,但成功率有限:我设法调用了该库导出的一些API

现在我正试图调用
nvmlDeviceGetHandleByIndex\u v2
,但我已经在这个问题上耽搁了很长时间。它接受一个
nvmlDevice\u t
指针,但我没有发现
nvmlDevice\u t
实际上超出了这一点:

问题是头文件没有对
nvmlDevice\u st
进行任何其他引用,因此我不知道要为它分配多少堆空间(如果有的话)。我发现这个函数调用相同的函数,如下所示:

nvmlDevice_t device;
CheckNVMLErrors(nvmlDeviceGetHandleByIndex(device_index, &device));
我的主要问题是,我对C/C++不够熟悉,无法理解
device
声明执行的隐式机制/内存分配,并且
nvml.h
头没有定义实际是什么


我试着用
ref int
参数调用它(用一个初始值
0
值),显然它确实有效,但如果可能的话,我想了解原因。作为参考,调用后该
ref int
参数的值为
1460391512
,以防从中发现一些东西。

如果查看源代码,这只是SDK使用的内部指针。它指向的值对您没有意义。您可以使用它来识别正在使用的设备

在Windows中思考
Handle
HWND
。调用类似于
FindWindow()
,它会将看似随机的值返回给您。您不在乎该值包含什么,只要在调用
GetWindowText()
或任何其他窗口方法时使用该值来标识该窗口即可


因此,使用
ref int
是正确的,但您需要的是指针。因此,您应该使用
out IntPtr
来获取值。

如果查看源代码,那只是SDK使用的内部指针。它指向的值对您没有意义。您可以使用它来识别正在使用的设备

在Windows中思考
Handle
HWND
。调用类似于
FindWindow()
,它会将看似随机的值返回给您。您不在乎该值包含什么,只要在调用
GetWindowText()
或任何其他窗口方法时使用该值来标识该窗口即可


因此,使用
ref int
是正确的,但您需要的是指针。因此,您应该使用
out IntPtr
来获取值。

您好,很有趣,如果您查看源代码,不确定这是否有帮助,这只是SDK使用的内部指针。它指向的值对您没有意义。您可以使用它来识别正在使用的设备。在windows中思考
Handle
HWND
。调用类似于
FindWindow()
,它会将看似随机的值返回给您。您不在乎该值是什么,只要在调用
GetWindowText()
或任何其他窗口方法时使用该值来标识该窗口即可。它是IntPtr,而不是int。将实现隐藏在句柄后面是一种非常古老的机制,可以鼓励语言独立性并避免api滥用。你的操作系统大量使用它们。谷歌“基于句柄的api”了解更多信息,中的答案不太好,但可能有助于了解情况。我尝试将其命名为
ref IntPtr
,其中一个变量初始化为
IntPtr.Zero
假设它是一个句柄,但我返回了一个无效的参数错误:(@HansPassant@Andytry
out IntPtr
hi,很有趣,如果您查看源代码,不确定这是否有帮助,那只是SDK使用的一个内部指针。它指向的值对您没有意义。您可以使用它来识别正在使用的设备。在windows中思考
Handle
HWND
。您可以调用类似于
FindWindow()
,它会将看似随机的值返回给您。您不在乎该值包含什么,只需在调用
GetWindowText()时使用该值来标识该窗口
或任何其他窗口方法。它是IntPtr,而不是int。将实现隐藏在句柄后面是一种非常古老的机制,可以鼓励语言独立性并避免api滥用。您的操作系统大量使用它们。Google“基于句柄的api”为了了解更多信息,中的答案不太好,但可能有助于了解情况。我尝试将其命名为
ref IntPtr
,其中一个变量初始化为
IntPtr.Zero
假设它是一个句柄,但我返回了一个无效参数错误:(@HansPassant@Andytry
out IntPtr
为了对您的答案进行一点扩展,这是最后的DllImport声明:
[DllImport(“nvidia-ml.dll”,CallingConvention=CallingConvention.Cdecl,EntryPoint=“nvmdevicegethandlebyindex_v2”)]公共静态外部返回代码GetDeviceHandleByIndex(int index,out IntPtr handle)
@Machinarius--非常好,很高兴它成功了:)我喜欢做那种事情。逆向工程是一件非常有趣的事情。为了进一步说明你的答案,这是最后的DllImport声明:
[DllImport(“nvidia-ml.dll”,CallingConvention=CallingConvention.Cdecl,EntryPoint=“nvmlDeviceGetHandleByIndex_v2”)]public static extern ReturnCodes GetDeviceHandleByIndex(int index,out IntPtr handle);
@Machinarius——太棒了,很高兴它成功了:)我喜欢做那种事情。逆向工程非常有趣。
nvmlDevice_t device;
CheckNVMLErrors(nvmlDeviceGetHandleByIndex(device_index, &device));