C # 4.0 PInvoke Issue (Библиотека ATI AGS) - PullRequest
0 голосов
/ 28 сентября 2010

Я загрузил библиотеку ATI AGS (ATI GPU Services) и пытаюсь получить некоторую базовую информацию о драйвере с помощью этого API из C #.Библиотека ATI AGS доступна для скачивания здесь:

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

Я написал немного кода на C # для извлечения информации о драйвере из графического процессора с помощью AGS API, но явозникли проблемы с вызовом неуправляемого метода.Я пробовал все виды различных перестановок параметров DllImportAttribute, но безрезультатно.Я получаю либо MarshalDirectiveException, либо pInvokeStackImbalance.

Я почти уверен, что это все из-за неверной подписи P / Invoke, но я исчерпал свои знания об этом API.

Кстати, кроме этого, вы увидите, что я использую 32-битную DLL, и мне кажется, что я продвигаюсь дальше, но когда я использую 64-битную DLL, я получаю исключение BadImageFormatException.

Вот код, который я использую:

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

Есть идеи?

Редактировать: Вот определение ATIAGSDriverGetVersionInfo ()функция в ati_ags.h.Согласно документации ATI AGS (PDF-файл включен в загрузку), в нем говорится, что нужно определить _ATI_AGS_USE_DLL, поэтому я добавил эту строку в начало моего файла кода класса C #:

Цитата документации

Определите, будут ли доступны функции AGS через DLL или статическую библиотеку.Если выбрана опция dll, обязательно определите _ATI_AGS_USE_DLL в свойствах вашего проекта.Если выбран параметр статической библиотеки 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;
}

Ответы [ 2 ]

1 голос
/ 19 ноября 2011

Это помогает мне ...

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

... кажется, что неправильное соглашение о вызовах вызывало проблемы (как уже отмечал Ричард)

0 голосов
/ 28 сентября 2010

В ati_ags.h структура AGSDriverVersionInfoStruct объявлена ​​следующим образом:

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

Вот как бы я объявил эквивалент в 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;
}
...