#c# #c #templates #marshalling
#c# #c #шаблоны #сортировка
Вопрос:
У меня очень ограниченные знания о C #. Моя цель — предоставить C dll API моему коллеге по C #. Библиотека dll должна быть на C по устаревшим причинам.
Вопрос — Может ли шаблонная функция C (показанная ниже из VS) быть маршалирована в C #?
class __declspec(dllexport) Foo
{
public:
template <typename T> T* getFoo(T* fooData){return fooData;};
};
Если нет, какие-либо предложения? Должен ли каждый тип, передаваемый в шаблонную функцию, иметь свою собственную функцию, чтобы C # мог ее маршалировать?
Комментарии:
1. @Yochai Это не тот же вопрос.
2. @Yochai: Этот вопрос касается не переноса, а взаимодействия. LEO все еще планирует использовать C для сборки DLL. Даже близко не похоже на обман.
Ответ №1:
Вопрос — Может ли шаблонная функция C (показанная ниже из VS) быть маршалирована в C #?
Нет. Не существует совместимого двоичного интерфейса с C # на C . Вы можете вызывать только экспортированные символы C из C #.
Теоретически, вы могли бы явно создать экземпляры шаблонов в C DLL, что приведет к тому, что они получат внешнюю привязку и записи в таблице символов экспорта. Но искажение имен сделает функции непригодными для всех практических целей. Следовательно, наилучшим способом является наличие промежуточного уровня, совместимого с C, который вызывает базовые функции C .
Комментарии:
1. Правильно, и это влияет не только на шаблоны, но и на классы.
2. Спасибо за быстрый ответ. Я думаю, что воспользуюсь идеей Rytmis и попытаюсь разработать API с использованием C / CLI
Ответ №2:
Я думаю, вам лучше всего написать свой код на C / CLI. Вы можете предоставить управляемый API, который может использоваться кодом C #, но при необходимости по-прежнему использовать собственный C .
Ответ №3:
Итак, через несколько недель мне удалось запустить что-то, и я подумал, что поделюсь этим с группой. (Прошу прощения за внешний вид псевдокода). Я в основном сам выучил C # вместо C / CLI.
Помните вопрос — Может ли шаблонная функция C (показанная ниже из VS) быть маршалирована в C #?
Моя работа заключается в следующем: выполните упорядоченные неуправляемые вызовы C # для функций C , которые могут переводить вызовы в метод шаблона.
Вот код:
//C code
//C Header
class __declspec(dllexport) Foo
{
public:
template <typename T> T* getFoo(T* fooData){return fooData;};
};
extern "C" __declspec(dllexport) void call_getFoo(Foo* pFoo, void* pfooData, int fooId)
{
switch(fooId)
{
case(ENUM::1) : //Use an enum here for a better switch statement.
{
//Cast the void pointer to a specific type so the template knows how to use it.
pFoo->getFoo((*TypeCast*)pfooData);
break;
}
}
}
//C# Code
internal static class UnsafeNativeMethods
{
const string _dllLocation = "Foo.dll";
[DllImport(_dllLocation)]
static public extern void call_getFoo(IntPtr pFoo, IntPtr pfooData, int fooId);
}
//In a C# method
...
...
//Marshal Up a C# data type to a pointer for C .
*YOUR TYPE HERE* myType;
int rawsize = Marshal.SizeOf(myType);
IntPtr pfooData = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(myType,pfooData,true);
//call the C dll
UnsafeNativeMethods.call_getFoo(pFoo, pfooData, fooId);
//Convert Ptr Back To myType
myType = (*YOUR TYPE HERE*) Marshal.PtrToStructure(pfooData, typeof(*YOUR TYPE HERE*));
...
...
Надеюсь, это поможет!