Я начал использовать swig несколько месяцев go, и после нескольких взлетов у меня появилась первая работающая оболочка c#. Теперь мне нужно создать оболочку в C#, которая обертывает интерфейс C, который принимает аргумент функции ptr. Я использовал typedef для функции ptr type и макрос swig cs_callback, который я нашел при исследовании того, как это сделать. Этот макрос необходим, чтобы swig мог сгенерировать полезный тип функции ptr (и имя). В противном случае swig создаст класс SWIGTYPE_p_f_p_InfoBarData__void, который сделает вещи ужасными и сложными.
К сожалению, я, кажется, застрял сейчас. AFAIK Должна происходить одна из двух вещей, которых нет.
1) делегат, соответствующий моему typedef для моей функции ptr, нигде не генерируется
typedef void (_stdcall uiDataObserverFun c) (uiData );
2) Если я попытаюсь использовать карту типов для вставки члена делегата в сгенерированный класс, ничего не произойдет.
Мне кажется, что выход моей глубины здесь и надежды, кто-то может дать мне некоторое представление о том, что происходит не так. Я приложил минимальный пример, который воспроизводимо вызывает у меня головную боль и необходимый файл проекта swig. В моей среде разработки я использую swig 4.0.1.
UiData.h
#pragma once
extern "C" {
struct UiData
{
double temperature;
};
}
UiDataProvider
#pragma once
#include "UiData.h"
typedef void (_stdcall *uiDataObserverFunc)(InfoBarData*);
#ifdef UI_EXPORTS
#define UI_API __declspec(dllexport)
#else
#define UI_API __declspec(dllimport)
#endif
extern "C" {
UI_API void UI_Init();
UI_API void UI_RegisterObserver(uiDataObserverFunc callbackFunc);
}
UiModule_cs.i
#define UI_EXPORTS
%module UiWrapper
// TYPE: name of the C function ptr typedef
// CSTYPE: name of the corrseponding delegate
%define %cs_callback(TYPE, CSTYPE)
%typemap(ctype) TYPE, TYPE& "void*"
%typemap(in) TYPE %{ $1 = ($1_type)$input; %}
%typemap(in) TYPE& %{ $1 = ($1_type)&$input; %}
%typemap(imtype, out="IntPtr") TYPE, TYPE& "CSTYPE"
%typemap(cstype, out="IntPtr") TYPE, TYPE& "CSTYPE"
%typemap(csin) TYPE, TYPE& "$csinput"
%enddef
%rename("%(strip:[UI_])s") "";
%cs_callback(uiDataObserverFunc, cppUiDataObserverCallback)
%typemap(cscode) UiWrapper %{
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate void cppUiDataObserverCallback(UiData* uiDataUpdate);
%}
%{
#include "UiData.h"
#include "UiDataProvider.h"
%}
// these headers have to come before anything else - otherwise syntax error(1) will be thrown
%include <windows.i>
%include <carrays.i>
%include <cpointer.i>
%include "UiData.h"
%include "UiDataProvider.h"
call "%swig%\swig.exe" -v -debug-typedef -c++ -csharp -o .\UiWrapper.cpp -outdir .\UiModuleSwig UiModule_cs.i
Я пытался
- , используя -E, чтобы увидеть, появляется ли что-то подозрительное после предварительной обработки, но но безрезультатно.
- переупорядочение блоков инструкций swig. Если что-то и происходило, то это ухудшалось.
- не использовал typedef для делегата (при условии, что я мог неправильно изменить поведение swig) -> без эффекта
С наилучшими пожеланиями и спасибо за ваше время, Фред