вызов dll-функции возвращающей void * (C#)
От: begemot Россия  
Дата: 21.01.08 05:43
Оценка:
Доброго времени суток !

имеется 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();

******* надо заменить на что то ... на что ?

спасибо.
Re: вызов dll-функции возвращающей void * (C#)
От: Аноним  
Дата: 21.01.08 06:54
Оценка: 3 (1)
[StructLayout(LayoutKind.Sequential)]
struct out_struct
{
public IntPtr buf;
public Int32 buf_size;
}

[DllImport("libdll.dll", CharSet = CharSet.Ansi)]
private static extern out_struct();

Для чтения из out_struct.buf использовать
int Marshal.ReadInt32(IntPtr Ptr);
Re: вызов dll-функции возвращающей void * (C#)
От: Decoy Литва  
Дата: 21.01.08 08:13
Оценка: 3 (1)
Здравствуйте, 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();
    }
}


Удачи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.