Достъп до C# статичен клас от C++ DLL

Получих задачата да напиша нов интерфейс към наследен C++ DLL, за който нямам изходния код, който - по независещи от мен причини - има директен достъп до глобален клас в наследеното приложение.

От приложението е нещо като:

extern Interface *App;

...

Interface App*;   //  A pointer to our interface class.

След това от наследената DLL:

if( App->GetStatus() ) return false;

Интерфейсният клас, към който се отнася приложението, е доста тривиален за пренаписване в C#, но как мога да го направя еквивалентен на extern, така че наследената C++ DLL да има достъп до него?

Благодаря!


person He Who Shall Not Be Named    schedule 30.03.2015    source източник
comment
Няма да стигнете много далеч с това, докато пишете Interface App*, разбирането на указатели е доста критично, за да стигнете до някъде. Извикването на C# код от C++ изисква първо да се зареди CLR. Има много начини да направите това по грешен начин, който започва с използването на лесните начини. Използването на директивата #import в C++ е правилен начин. Обучете се, попитайте вашия ръководител за ресурсите, от които се нуждаете.   -  person Hans Passant    schedule 31.03.2015
comment
Имайте предвид, че авторът е казал, че няма достъп до изходния код на C++, така че зареждането на CLR може да е проблем...   -  person nevada_scout    schedule 01.04.2015


Отговори (1)


Можете да опитате да използвате пакета nuget на Robert Giesecke „UnmanagedExports“, за да постигнете тази функционалност така:

class Test
{
    [DllExport("add", CallingConvention = CallingConvention.Cdecl)]
    public static int TestExport(int left, int right)
    {
       return left + right;
    } 
}

Въпреки това:

a) Вярвам, че това работи само за методи, а не за класове и

б) причината, поради която няма собствен начин за експортиране на DLL в C#, е, че извикващото приложение трябва да има заредена .NET рамка, за да има достъп до тази входна точка. Това се отнася и за пакета UnmanagedExports nuget, към който свързах по-горе.

Можете да заобиколите това, като накарате вашето C++ приложение да зареди моно, преди да извикате C# приложението, но не звучи така, сякаш това е възможно във вашия случай.

(Освен това UnmanagedExports ще работи само ако изрично зададете цел за изграждане в свойствата на вашия проект – напр. x86)

person nevada_scout    schedule 30.03.2015
comment
.net Framework се зарежда веднага щом бъде извикан един от вашите експортирани методи. Вашето c++ приложение може дори да използва различна версия на рамката. - person jbriggs; 31.03.2015
comment
Това се случва само ако приложението ви е написано на C++/CLI. Ако вашият C++ код е неуправляван, той няма да зареди .net framework - person nevada_scout; 31.03.2015
comment
Компилирах собствена C++ програма от командния ред cl /EHsc MyConsoleApp.cpp /Fe: MyConsoleApp.exe В cpp файла имам typedef void (__stdcall * OPENDEVICES)(); OPENDEVICES OpenDevices; HINSTANCE hGetProcIDDLL = LoadLibrary("MyCSharpLib.dll"); OpenDevices = OPENDEVICES(GetProcAddress(HMODULE(hGetProcIDDLL), "OpenDevices") ); Това работи. MyCSharplib.dll е създаден с .Net 4.0. Имам клиент, който използва Visual Studio 2005 и няма проблем с използването на това приложение. - person jbriggs; 31.03.2015