Маршалинг массива структур.
От: Defazze  
Дата: 26.07.08 06:47
Оценка:
Добрый день.
Суть проблемы: есть сишная длл-ка без исходников, только заголовочный файл с комментариями. Вот описание интересующей функции, которую я пытаюсь вызвать из с#:


// FullName:  TCL_GetProviderList
// Returns:   DWORD - TCL_ERROR_SUCCESS в случае успешного выполнения. В случае ошибки - см. коды ошибок.
// Parameter: IN_OUT DWORD *pdwListSize - указатель на размер требуемого массива структур TCL_PROV_INFO.
// Parameter: OUT TCL_PROV_INFO **pProvList - указатель на массив структур TCL_PROV_INFO. В случае если массив
//              имеет значение NULL, тогда функция возвращает длину требуетого массива.
//************************************************************************************************************
EXTERN_C ATCL_EXPORT DWORD ATCL_STDCALL TCL_GetProviderList(
    IN_OUT DWORD         *pdwListSize,
    OUT    TCL_PROV_INFO **pProvList = NULL);


Вот таким вот образом я пытаюсь вызвать ее из с#:


[DllImport("atcl.dll")]
        public static extern int TCL_GetProviderList(out int lListSize, out IntPtr ProvList);


с тем, чтобы в дальнейшем при помощи Marshal.PtrToStructure вытащить нужный массив.

Но тут начинаются странности. Функция возвращает ненулевой размер массива, однако возвращаемый указатель всегда IntPtr.Zero. Можно было бы предположить, что проблема в сишной функции, однако код VBA, работающий с этой же функцией, отрабатывает безупречно:


Public Type TCL_PROV_INFO
    ProvName As String
    dwType As Long
End Type

Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal s As String) As Long
Declare Function GetProviderList Lib "aTCL.dll" Alias "#13" (ByRef lListSize As Long, _
                    ByRef ProvList() As TCL_PROV_INFO) As Long
                    
Public Sub test()
Dim ProvList() As TCL_PROV_INFO, lSize As Long, i As Long

LoadLibrary ("atcl.dll")

GetProviderList ProvList, lSize
ReDim ProvList(1 To lSize)
GetProviderList ProvList, lSize
      
For i = 1 To lSize
        Debug.Print ProvList(i).ProvName
Next i

End Sub



Попытка вернуть не указатель, а непосредственно массив структур:

[DllImport("atcl.dll")]
        public static extern int TCL_GetProviderList(out int lListSize, out TCL_PROV_INFO[] ProvList);


так же не приносит успеха: в переменной ProvList содержится NULL.

В обоих вариантах вызова возвращаемый код ошибки — 0, т.е. функция отрабатывает корректно.

Помогите пожалуйста забороть эту проблему.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.