Доброго времени суток !
имеется DLL написанная на с++. В длл имеется функция которая описывается в h-файле как:
struct out_struct
{
void* buf;
int buf_size;
} ;
out_struct WINAPI func(void);
как импортировать такую структуру т.е. не только структуру, но и данные, которые возвращаются при вызове данной функции ?
это будет выглядеть конечно вот так:
[DllImport("libdll.dll", CharSet = CharSet.Ansi)]
private static extern ********* func();
******* надо заменить на что то ... на что ?
спасибо.
Здравствуйте, begemot, Вы писали:
B>Доброго времени суток !
B>это будет выглядеть конечно вот так:
B>B>[DllImport("libdll.dll", CharSet = CharSet.Ansi)]
B>private static extern ********* func();
B>
B>******* надо заменить на что то ... на что ?
В общем набросал маленький пример, функция func() в MyLibrary.dll возвращает в buf строчку с описанием последней ошибки и в buf_size длину буфера
// MyLibrary.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
struct out_struct
{
void* buf;
int buf_size;
};
extern "C" __declspec(dllexport) out_struct WINAPI func()
{
LPVOID lpMsgBuff;
LPVOID lpDisplayBuff;
DWORD dwError = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuff,
0,
NULL);
lpDisplayBuff = (LPTSTR) LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR) lpMsgBuff) + 64) * sizeof(TCHAR));
wsprintf((LPTSTR) lpDisplayBuff, TEXT("GetLastError(%d) = %s"), dwError, lpMsgBuff);
//MessageBox(NULL, (LPTSTR)lpDisplayBuff, NULL, MB_OK);
out_struct *outParam = new out_struct();
outParam->buf = calloc(lstrlen((LPCTSTR) lpDisplayBuff), sizeof(TCHAR));
memcpy(outParam->buf, lpDisplayBuff, lstrlen((LPCTSTR) lpDisplayBuff) * sizeof(TCHAR)); //lstrcpy()
outParam->buf_size = lstrlen((LPCTSTR) lpDisplayBuff) * sizeof(TCHAR);
LocalFree(lpDisplayBuff);
LocalFree(lpMsgBuff);
return (*outParam);
}
Ну а код на C# выглядит вот так :
using System.Runtime.InteropServices;
namespace ConsoleApp_TestDLLImport
{
class Program
{
static void Main(string[] args)
{
out_struct outParam = func();
int buf_size = outParam.buf_size;
string buf = Marshal.PtrToStringAuto(outParam.buf, buf_size); //операция необходимая тут, зависит от типа данных, который возвращает dll
Console.WriteLine("buf={0}, buf_size={1}", buf, buf_size);
Console.ReadLine();
}
[StructLayout(LayoutKind.Sequential)]
struct out_struct
{
public IntPtr buf;
public Int32 buf_size;
}
[DllImport("MyLibrary.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
private static extern out_struct func();
}
}
Удачи!