从C#调用非托管代码

VikFreeze

借助OpenHardwareMonitor项目的一些启发,我使自己成为监视CPU和GPU指标温度,负载等的好工具。

它工作正常,但是PInvokeStackImbalance在调用NVidia驱动程序方法时遇到警告,并且认为忽略它们是不明智的。

但是,经过数周的实验(手持NVidia Documentaion)之后,我仍然无法弄清如何以VS 2015满意的方式定义和使用驱动程序结构和方法-奇怪的是,由于其中没有警告尽管使用完全相同的代码,但OpenHardwareMonitor项目。

希望这里有人可以指出正确的方向。

[DllImport("nvapi.dll", CallingConvention = CallingConvention.Cdecl, PreserveSig = true)]
private static extern IntPtr nvapi_QueryInterface(uint id);

private delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate([Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
private static readonly NvAPI_EnumPhysicalGPUsDelegate NvAPI_EnumPhysicalGPUs;

NvAPI_EnumPhysicalGPUs = Marshal.GetDelegateForFunctionPointer(nvapi_QueryInterface(0xE5AC921F), typeof(NvAPI_EnumPhysicalGPUsDelegate)) as NvAPI_EnumPhysicalGPUsDelegate;

status = NvAPI_EnumPhysicalGPUs != null ? NvAPI_EnumPhysicalGPUs(PhysicalGPUHandles, out PhysicalGPUHandlesCount) : NvStatus.FUNCTION_NOT_FOUND; // warning is thrown here
a安

首先,函数是C样式的,而不是C ++。这很幸运,因为直接从C#与C ++互操作是一个巨大的痛苦(在这种情况下,您确实想使用C ++ / CLI)。

原生互操作并不容易。您需要了解谁拥有什么内存,如何分配和取消分配内存,并且需要特别注意运行的是32位还是64位。

乍一看,您在委托上缺少调用约定,因此它将默认为StdCall但是,根据NVAPI中的定义(对于互操作库来说,这是非常合理的),您应该使用Cdecl

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
private delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate([Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);

Cdecl和StdCall的棘手之处在于两者非常相似(参数从右至左传递到堆栈上,如果是整数或poitner等,则返回值以EAX表示),除了在Cdecl中,调用者负责清除堆栈,而在StdCall中,这是被调用者的工作。这意味着使用StdCall而不是Cdecl的P / Invoking几乎总是可以工作(.NET运行时会注意到堆栈不平衡并进行了修复),但是会产生警告。

如果这不能解决您的问题,请注意位数。尝试使用32位.NET应用程序中的32位库。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从 c# 调用非托管代码。使用 IntPtr 获取数据

来自分类Dev

从C#调用非托管C ++

来自分类Dev

从C#调用非托管C ++

来自分类Dev

对静态库的非托管C#调用

来自分类Dev

C#非托管代码调用不起作用:AddConsoleAlias

来自分类Dev

P /调用-从C#调用非托管DLL

来自分类Dev

将 C++ 非托管代码转换为 C#

来自分类Dev

从非托管C ++ / CLI调用重载的C#数组访问

来自分类Dev

整理结构数组以从C#调用非托管函数

来自分类Dev

用指针调用非托管代码

来自分类Dev

非托管C#与C ++

来自分类Dev

导出托管的C#函数以将更改的char *参数返回到非托管代码

来自分类Dev

托管代码与非托管代码

来自分类Dev

从C#调用C ++ dll。“无法封送'返回值':无效的托管/非托管类型组合。”

来自分类Dev

非托管C ++代码上的NullReferenceException

来自分类Dev

从非托管C ++代码访问WPF

来自分类Dev

是否可以通过[DllImport]属性将Java“非托管”代码导入C#?

来自分类Dev

使用C#在非托管代码中将委托传递给回调函数

来自分类Dev

将托管引用(this)传递给非托管代码并调用托管回调

来自分类Dev

从Delphi应用程序调用带有SerialPort类的C#非托管导出dll

来自分类Dev

从C#调用托管C ++中的向量

来自分类Dev

在C#中使用非托管DLL

来自分类Dev

c#创建非托管对象*数组

来自分类Dev

从托管DLL C#调用方法

来自分类Dev

C#中非托管DLL的调用约定

来自分类Dev

从C#调用非托管C DLL函数(具有指向struct的指针和指向bool数组的指针)

来自分类Dev

在从托管C#应用程序进行的非托管C ++ Dll调用中,如何处理数据类型之间的冲突

来自分类Dev

Microsoft Fake框架是否支持C ++ /非托管代码

来自分类Dev

C#-从非托管代码返回类型int *

Related 相关文章

  1. 1

    从 c# 调用非托管代码。使用 IntPtr 获取数据

  2. 2

    从C#调用非托管C ++

  3. 3

    从C#调用非托管C ++

  4. 4

    对静态库的非托管C#调用

  5. 5

    C#非托管代码调用不起作用:AddConsoleAlias

  6. 6

    P /调用-从C#调用非托管DLL

  7. 7

    将 C++ 非托管代码转换为 C#

  8. 8

    从非托管C ++ / CLI调用重载的C#数组访问

  9. 9

    整理结构数组以从C#调用非托管函数

  10. 10

    用指针调用非托管代码

  11. 11

    非托管C#与C ++

  12. 12

    导出托管的C#函数以将更改的char *参数返回到非托管代码

  13. 13

    托管代码与非托管代码

  14. 14

    从C#调用C ++ dll。“无法封送'返回值':无效的托管/非托管类型组合。”

  15. 15

    非托管C ++代码上的NullReferenceException

  16. 16

    从非托管C ++代码访问WPF

  17. 17

    是否可以通过[DllImport]属性将Java“非托管”代码导入C#?

  18. 18

    使用C#在非托管代码中将委托传递给回调函数

  19. 19

    将托管引用(this)传递给非托管代码并调用托管回调

  20. 20

    从Delphi应用程序调用带有SerialPort类的C#非托管导出dll

  21. 21

    从C#调用托管C ++中的向量

  22. 22

    在C#中使用非托管DLL

  23. 23

    c#创建非托管对象*数组

  24. 24

    从托管DLL C#调用方法

  25. 25

    C#中非托管DLL的调用约定

  26. 26

    从C#调用非托管C DLL函数(具有指向struct的指针和指向bool数组的指针)

  27. 27

    在从托管C#应用程序进行的非托管C ++ Dll调用中,如何处理数据类型之间的冲突

  28. 28

    Microsoft Fake框架是否支持C ++ /非托管代码

  29. 29

    C#-从非托管代码返回类型int *

热门标签

归档