Как мне вызвать функцию c из C # - PullRequest
0 голосов
/ 21 мая 2011

Я хотел бы использовать эту функцию C в C #:

typedef void (*WRITE_CALLBACK)(int hMountEnv, unsigned __int64 NumBytesWritten, 
               void* pContext);

Как мне определить это, чтобы я мог назвать это?

Нужно ли что-нибудь еще делать, чтобы эта работа

Ответы [ 2 ]

1 голос
/ 21 мая 2011

Это больше похоже на делегата, чем на саму функцию / метод. Вы бы не назвали это, это будет предоставлено как указатель функции на что-то другое. Эквивалентом может быть что-то вроде этого:

public delegate void WRITE_CALLBACK(int hMountEnv, uint numBytesWritten, object pContext);
1 голос
/ 21 мая 2011

Посмотрите на http://msdn.microsoft.com/en-us/library/ektebyzx(v=vs.80).aspx, как маршалировать указатели функций. Внизу этой страницы есть пример.

Я сделаю для вас C #, и, поскольку я не знаю, в каком направлении движется указатель, я покажу оба. Есть некоторые ошибки, которые могут быть проблематичными для вас в отношении соглашений о вызовах. Marshal.GetDelegateForFunctionPointer и Marshal.GetFunctionPointerForDelegate предполагают, что указатель функции будет StdCall, поэтому, если у вас нет доступа к неуправляемой библиотеке, чтобы убедиться, что указатель функции является стандартным вызовом (я думаю, что C по умолчанию использует cdecl, к сожалению), вам придется создайте неуправляемую библиотеку shim для изменения соглашения о вызовах, если не существует другого способа, о котором я не знаю.

Это будет заголовок C DLL, которую я назвал "UnmanagedLib.dll".

typedef void ( __stdcall *WRITE_CALLBACK)(int hMountEnv, unsigned __int64 NumBytesWritten, void* pContext);

extern "C" {
__declspec(dllexport) WRITE_CALLBACK __stdcall FunctionProducingFunctionPointer(void);
__declspec(dllexport) void __stdcall FunctionConsumingFunctionPointer(WRITE_CALLBACK callback);
}

Это будет файл CPP DLL.

#include "UnmanagedLib.h"

void __stdcall SampleFunction(int hMountEnv, unsigned __int64 NumBytesWritten, void* pContext)
{
}

WRITE_CALLBACK __stdcall FunctionProducingFunctionPointer(void)
{
    return &SampleFunction;
}

void __stdcall FunctionConsumingFunctionPointer(WRITE_CALLBACK callback)
{
    // sample call
    (*callback)(0,0,NULL);
}

И, наконец, это программа на C # для использования DLL.

class Program
{
    public delegate void WRITE_CALLBACK(int hMountEnv, ulong NumBytesWritten, IntPtr pContext);

    [DllImport("UnmanagedLib.dll")]
    public static extern IntPtr FunctionProducingFunctionPointer();

    [DllImport("UnmanagedLib.dll")]
    public static extern void FunctionConsumingFunctionPointer(IntPtr functionPointer);

    public static void SampleFunction(int hMountEnv, ulong NumBytesWritten, IntPtr pContext)
    {
    }

    static void Main(string[] args)
    {
        var functionDelegateToManagedSampleFunction = new WRITE_CALLBACK(SampleFunction);
        var functionDelegateToUnmanagedSampleFunction = Marshal.GetDelegateForFunctionPointer(FunctionProducingFunctionPointer(), typeof(WRITE_CALLBACK));

        // call the unmanaged sample function via its pointer
        functionDelegateToUnmanagedSampleFunction.DynamicInvoke(new object[] {0,0ul,null});

        // pass the managed sample function to the unmanaged code
        FunctionConsumingFunctionPointer(Marshal.GetFunctionPointerForDelegate(functionDelegateToManagedSampleFunction));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...