如何在C#中用未知结构P/调用函数?
我知道这听起来很奇怪,但我甚至不知道如何正确地问这个问题。我一直在尝试P/Invoke到NVidia的NVML库中,但成功率有限:我设法调用了该库导出的一些API 现在我正试图调用如何在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进行任何其他引用,因此我不知道要为它分配多少堆空间(如果有的话)。
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@Andytryout IntPtr
hi,很有趣,如果您查看源代码,不确定这是否有帮助,那只是SDK使用的一个内部指针。它指向的值对您没有意义。您可以使用它来识别正在使用的设备。在windows中思考Handle
或HWND
。您可以调用类似于FindWindow()
,它会将看似随机的值返回给您。您不在乎该值包含什么,只需在调用GetWindowText()时使用该值来标识该窗口
或任何其他窗口方法。它是IntPtr,而不是int。将实现隐藏在句柄后面是一种非常古老的机制,可以鼓励语言独立性并避免api滥用。您的操作系统大量使用它们。Google“基于句柄的api”为了了解更多信息,中的答案不太好,但可能有助于了解情况。我尝试将其命名为ref IntPtr
,其中一个变量初始化为IntPtr.Zero
假设它是一个句柄,但我返回了一个无效参数错误:(@HansPassant@Andytryout 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));