Добрый день.
Суть проблемы: есть сишная длл-ка без исходников, только заголовочный файл с комментариями. Вот описание интересующей функции, которую я пытаюсь вызвать из с#:
// 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, т.е. функция отрабатывает корректно.
Помогите пожалуйста забороть эту проблему.