Дело такое: Написал несколько функций на С++ и хочу их использовать в C# коде, но не знаю как правильно объявить эти функции в C#.
C функциями int CreateNewConverter()
и void DestroyConverter(/*in*/ int id)
вроде бы понятно, но вот void Convert(int converterID, IDeckLinkVideoFrame *srcFrame, byte **dstArray))
вызывает сомнения в правильности оформления и удобства использования в C#, потому что у меня тут данные в библиотеку передаются и забираются через указатели.
Отмечу, что IDeckLinkVideoFrame *srcFrame
это указатель на COM (Component Object Model) объект реализующий интерфейс `IDeckLinkVideoFrame, так что, я полагаю, наверное, можно передать его с помощью IntPtr, но я не знаю как.
Прошу помочь: укажите на ошибки, посоветуйте как правильнее, помогите решить.
H-файл:
#ifdef DLFC_EXPORTS
#define DLFC_API __declspec(dllexport)
#else
#define DLFC_API __declspec(dllimport)
#endif
using namespace std;
static unordered_map<int, VideoConverterARGB32*> Dictionary;
static int ID = 0;
extern "C" {
DLFC_API int CreateNewConverter();
DLFC_API void DestroyConverter( /*in*/ int id);
DLFC_API void Convert( /*in*/ int converterID,
/*in*/ IDeckLinkVideoFrame *srcFrame,
/*out*/ byte **dstArray);
}
CPP-файл:
using namespace std;
int CreateNewConverter() {
ID++;
VideoConverterARGB32* conv = new VideoConverterARGB32();
Dictionary[ID] = conv;
return ID;
}
void DestroyConverter(/*in*/ int id) {
VideoConverterARGB32* conv = Dictionary[id];
Dictionary.erase(id);
delete conv;
}
void Convert(/*in*/ int converterID,
/*in*/ IDeckLinkVideoFrame *srcFrame,
/*out*/ byte **dstArray)
{
VideoConverterARGB32* conv = Dictionary[converterID];
conv->Convert(srcFrame, dstArray);
}
С#:
using System.Runtime.InteropServices;
using DeckLinkAPI;
namespace AR.CaptureDevices.DeckLink {
public class DeckLinkConverter {
[DllImport(dllName: "DeckLinkConverter")]
public static extern int CreateNewConverter();
[DllImport(dllName: "DeckLinkConverter")]
public static extern void DestroyConverter([Out] int id);
[DllImport(dllName: "DeckLinkConverter")]
public static extern void Convert([In]int converterID, [In] IDeckLinkVideoFrame* srcFrame, [Out] byte** dstArray);
}
}
Есть несколько вариантов.
Самый простой вариант - получение ссылки
List<string> list1 = new List<string>();
GCHandle handle1 = GCHandle.Alloc(list1);
IntPtr parameter = (IntPtr) handle1;
// call WinAPi and pass the parameter here
// then free the handle when not needed:
handle1.Free();
// back to object (in callback function):
GCHandle handle2 = (GCHandle) parameter;
List<string> list2 = (handle2.Target as List<string>);
list2.Add("hello world");
Полученная ссылка для чистого массива - будет указывать на массив (скорее всего).
Плюс в Marshal
есть много полезностей, например: ReadByte
, WriteByte
, PtrToStringAnsi
, StringToBSTR
, Copy
и другие.
Ccылка http://stackoverflow.com/questions/17339928/c-sharp-how-to-convert-object-to-intptr-and-back
Для передачи указателя на интерфейс, в Marshal
есть GetComInterfaceForObject
.
ссылка http://www.codeproject.com/Articles/612604/Best-Practice-in-Writing-a-COM-Visible-Assembly-Cs
Так же, если есть интерфейс в с++, то можно его подхватить на с# по ссылке, используя Marshal.GetTypedObjectForIUnknown
.
Так же можно передавать COM автоматически, для этого нужно, что б интерфейс был помечен как COM
[ComVisible(true)]
public interface IDeckLinkVideoFrame :IUnknown {
//...
}
И процедура вызова с с++ была в с# обьявлена примерно так
[DllImport(dllName: "DeckLinkConverter")]
void Convert(
[In][MarshalAs(UnmanagedType.I4)]int converterID,
[In][MarshalAs(UnmanagedType.Interface)]IDeckLinkVideoFrame srcFrame,
[Out][MarshalAs(UnmanagedType.LPArray)] byte **dstArray);
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Подскажите, как при нажатии на кнопку пролистать Panel через AutoScroll, таким образом, чтобы пролистывание уходило в самый конец Panel
Подскажите, выходит ошибка при получении пользователя из AD: "Ссылка на объект не указывает на экземпляр объекта"Хотя на компе где пишется...
Сейчас вывод изображений осуществляется с помощью счетчика в 3 промежутках: