C#4.0 PInvoke发行版(ATI AGS库)
我下载了ATI AGS(ATI GPU服务)库,并试图使用此API从C#检索一些基本的驱动程序信息。ATI AGS库可从以下位置下载: 我编写了一些C代码,使用AGSAPI从GPU中提取驱动程序信息,但是调用非托管方法时遇到了一些问题。我尝试了DllImportAttribute参数的各种不同排列,但都没有成功。我得到的不是MarshalDirectiveException就是PinvokesTack 我很确定这都是由于一个不正确的p/Invoke签名造成的,但是我已经用尽了我对这个API的知识 顺便说一句,你会发现我使用的是32位DLL,而且我似乎离它越来越远,但是当我使用64位DLL时,我得到了一个BadImageFormatException 以下是我正在使用的代码:C#4.0 PInvoke发行版(ATI AGS库),c#,.net,c#-4.0,pinvoke,C#,.net,C# 4.0,Pinvoke,我下载了ATI AGS(ATI GPU服务)库,并试图使用此API从C#检索一些基本的驱动程序信息。ATI AGS库可从以下位置下载: 我编写了一些C代码,使用AGSAPI从GPU中提取驱动程序信息,但是调用非托管方法时遇到了一些问题。我尝试了DllImportAttribute参数的各种不同排列,但都没有成功。我得到的不是MarshalDirectiveException就是PinvokesTack 我很确定这都是由于一个不正确的p/Invoke签名造成的,但是我已经用尽了我对这个API的知
[DllImport(
"atiags.dll"
, PreserveSig=false
, ExactSpelling=true
, ThrowOnUnmappableChar=true
, CharSet=CharSet.Unicode
, EntryPoint="agsDriverGetVersionInfo"
)]
public static extern void agsDriverGetVersionInfo(
[MarshalAs(UnmanagedType.Struct)]
out agsDriverVersionInfoStruct DriverInfo
);
public static agsDriverVersionInfoStruct GetAgsDriverVersion()
{
agsDriverVersionInfoStruct DriverInfo = new agsDriverVersionInfoStruct();
agsDriverGetVersionInfo(out DriverInfo);
}
public struct agsDriverVersionInfoStruct
{
[MarshalAs(UnmanagedType.LPTStr)]
public string strDriverVersion;
[MarshalAs(UnmanagedType.LPStr)]
public string strCatalystVersion;
[MarshalAs(UnmanagedType.LPStr)]
public string strCatalystWebLink;
}
有什么想法吗
编辑:以下是ati_ags.h中ATIAGSDriverGetVersionInfo()函数的定义。根据ATI AGS文档(下载中包含的PDF文件),它说要定义_ATI_AGS_USE_DLL,因此我在C类代码文件的顶部添加了这一行:
文件报价
确定是否通过dll或静态库访问AGS功能。如果选择了dll选项,请确保在项目属性中定义_ATI_AGS_USE_dll。如果选择了static lib选项,则不需要定义特殊令牌
__inline AGSReturnCode ATIAGSDriverGetVersionInfo( AGSDriverVersionInfoStruct *lpDriverVersionInfo )
{
AGSReturnCode iReturnValue = AGS_SUCCESS;
// Validate params
if ( NULL == lpDriverVersionInfo )
{
return AGS_FAILURE;
}
#ifdef _ATI_AGS_USE_DLL
// Load the lib
HINSTANCE lib = NULL;
lib = LoadLibrary(TEXT("atiags.dll"));
if (NULL == lib)
{
lib = LoadLibrary(TEXT("atiags64.dll"));
if (NULL == lib)
{
return AGS_FAILURE;
}
}
// Get the function pointer
AGSDRIVERGETVERSIONINFO agsDriverGetVersionInfo = NULL;
agsDriverGetVersionInfo = (AGSDRIVERGETVERSIONINFO)GetProcAddress(lib, "agsDriverGetVersionInfo");
if (NULL == agsDriverGetVersionInfo)
{
FreeLibrary(lib);
return AGS_FAILURE;
}
#endif // _ATI_AGS_USE_DLL
// Get the number of GPUs
iReturnValue = agsDriverGetVersionInfo( lpDriverVersionInfo );
#ifdef _ATI_AGS_USE_DLL
// Free the lib
FreeLibrary(lib);
#endif // _ATI_AGS_USE_DLL
return iReturnValue;
}
在
ati_ags.h
中,AGSDriverVersionInfoStruct
结构声明如下:
typedef struct _AGSDriverVersionInfoStruct {
char strDriverVersion[256];
char strCatalystVersion[256];
char strCatalystWebLink[256];
} AGSDriverVersionInfoStruct;
下面是我如何用C#声明等价物的方法:
这对我来说很有用
public enum AGSReturnCode
{
AGS_ERROR_MISSING_DLL = -2,
AGS_ERROR_LEGACY_DRIVER = -1,
AGS_FAILURE = 0,
AGS_SUCCESS = 1
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct AGSDriverVersionInfoStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strCatalystVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strCatalystWebLink;
}
public static class AGSharp
{
[DllImport("atiags.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "agsDriverGetVersionInfo")]
public static extern AGSReturnCode agsDriverGetVersionInfo(out AGSDriverVersionInfoStruct driver_info);
}
。。。似乎错误的调用约定造成了麻烦(正如Richard已经指出的)那么这在.NET 3.5及以下版本上有效吗?我尝试针对.NET 2.0框架,但遇到了ExecutionEngineeException。当我调用agsDriverGetVersionInfo()时,所有问题都会发生。您必须使用与C示例代码相同的方法。P/Invoke声明在这里不起作用。
pinvokestackproperty
表明您使用错误的调用约定调用该方法:DllImportAttribute
的CallingConvention
属性的哪些值尝试过?顺便说一句,我看不出为什么p/invoke不能正常工作。你能详细说明一下吗?为什么我不能使用P/Invoke?谢谢,我会试一试。无法封送类型为“ATI_Config_Reader.agsDriverVersionInfoStruct”的字段“strDriverVersion”:结构或类字段不能为StringBuilder类型。通常可以通过使用字符串字段并将其预初始化为长度与相应缓冲区长度匹配的字符串来实现相同的效果。尝试使用SizeConst
并改为使用String
。尝试更改回System.String并在构造函数中将其初始化为256个字符……[StructLayout](LayoutKind.Sequential)]公共结构AgsDriverVersionInfo结构{[Marshallas(UnmanagedType.LPStr,SizeConst=256)]公共字符串strDriverVersion;[Marshallas(UnmanagedType.LPStr,SizeConst=256)]公共字符串strCatalystVersion;[Marshallas(UnmanagedType.LPStr,SizeConst=256)]公共字符串strCatalystWebLink;公共AgsDriverVersionInfo结构(int伪){strDriverVersion=“”;strCatalystVersion=“”;strCatalystWebLink=“”;}}
public enum AGSReturnCode
{
AGS_ERROR_MISSING_DLL = -2,
AGS_ERROR_LEGACY_DRIVER = -1,
AGS_FAILURE = 0,
AGS_SUCCESS = 1
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct AGSDriverVersionInfoStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strCatalystVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strCatalystWebLink;
}
public static class AGSharp
{
[DllImport("atiags.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "agsDriverGetVersionInfo")]
public static extern AGSReturnCode agsDriverGetVersionInfo(out AGSDriverVersionInfoStruct driver_info);
}