2010-09-28 4 views
0

J'ai téléchargé la librairie ATI AGS (ATI GPU Services) Libary et j'essaie de récupérer des informations de base sur le pilote à l'aide de cette API, à partir de C#. La bibliothèque AGS ATI est disponible en téléchargement à partir d'ici:C# 4.0 Problème PInvoke (bibliothèque ATI AGS)

http://developer.amd.com/gpu/ags/Pages/default.aspx

J'ai écrit un peu de code C# pour extraire des informations du pilote du GPU en utilisant l'API AGS, mais je vais avoir quelques problèmes d'appeler le non géré méthode. J'ai essayé toutes sortes de permutations différentes des paramètres DllImportAttribute, en vain. Je reçois soit une MarshalDirectiveException ou un pInvokeStackImbalance. Je suis à peu près sûr que tout cela est dû à une signature P/Invoke incorrecte, mais j'ai épuisé mes connaissances de cette API. En passant, en passant, vous verrez que j'utilise la DLL 32 bits, et je semble aller plus loin avec elle, mais quand j'utilise la DLL 64 bits, je reçois un BadImageFormatException.

Voici le code que j'utilise:

[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; 
    } 

Toutes les idées?

Editer: Voici la définition de la fonction ATIAGSDriverGetVersionInfo() dans ati_ags.h. Selon la documentation AGS ATI (au format PDF inclus dans le téléchargement), il est dit de définir _ATI_AGS_USE_DLL, donc j'ajouté cette ligne en haut de mon C fichier # Code de classe:

Documentation Citation

Déterminer si La fonctionnalité AGS sera accessible via une DLL ou une bibliothèque statique. Si l'option dll est choisie, assurez-vous de définir _ATI_AGS_USE_DLL dans les propriétés de votre projet. Si l'option static lib est choisie, aucun jeton spécial n'a besoin d'être défini.

__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; 
} 
+0

Donc cela fonctionne sur .NET 3.5 et moins? – leppie

+0

J'ai essayé de cibler le framework .NET 2.0 et j'ai obtenu une exception ExecutionEngineException. Tous les problèmes se produisent lorsque j'appelle agsDriverGetVersionInfo(). –

+0

Vous allez devoir utiliser la même approche que l'exemple de code C. Les déclarations P/Invoke ne fonctionneront pas ici. – leppie

Répondre

1

Cela fait l'affaire pour moi ...

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); 
} 

... semble que la mauvaise convention d'appel causait des problèmes (comme Richard l'a déjà fait remarquer)

0

En ati_ags.h la struct AGSDriverVersionInfoStruct est déclarée comme suit:

typedef struct _AGSDriverVersionInfoStruct { 
    char strDriverVersion[256]; 
    char strCatalystVersion[256]; 
    char strCatalystWebLink[256]; 
} AGSDriverVersionInfoStruct; 

Voici comment je déclarerais l'équivalent en C#:

[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; 
} 
+0

Merci, je vais essayer. –

+0

Impossible de rassembler le champ 'strDriverVersion' du type 'ATI_Config_Reader.agsDriverVersionInfoStruct': Les champs Struct ou Class ne peuvent pas être de type StringBuilder. Le même effet peut généralement être obtenu en utilisant un champ String et en le préinitialisant sur une chaîne dont la longueur correspond à la longueur du tampon approprié. –

+0

Essayez avec 'SizeConst' et utilisez' string' à la place. –