[ComVisible(true)] [StructLayout(LayoutKind.Sequential)] public struct Entity { // entity external id public int id; [MarshalAs(UnmanagedType.BStr)] // entity name public string name; }
#import ".\\..\\Managed.Csharp\\bin\\Debug\\Managed.Csharp.tlb" no_namespace
public interface IExternalApplication { /// <summary> /// Returns the <see cref="Entity"/> instance. /// </summary> /// <returns></returns> Entity GetEntity(int id); }
public class Program { private static IExternalApplication _externalApplication; /// <summary> /// Sets the <see cref="IExternalApplication"/> interface. /// </summary> /// <param name="externalApplication"></param> /// <returns></returns> public static void SetExternalApplication(IExternalApplication externalApplication) { _externalApplication = externalApplication; // test var entity = _externalApplication.GetEntity(1234); MessageBox.Show(string.Format("Id={0}; Name={1}", entity.id, entity.name)); } }
typedef void* (__cdecl *GetEntityFunc)(int); public ref class ExternalApplication: public IExternalApplication { public: // constructor ExternalApplication(HMODULE win32Handle); virtual Entity GetEntity(int id); private: GetEntityFunc m_GetEntity; }; ExternalApplication::ExternalApplication(HMODULE win32Handle) { // initialize functions m_GetEntity = (GetEntityFunc)GetProcAddress(win32Handle, "GetEntity"); } Entity ExternalApplication::GetEntity(int id) { void *entityPtr = m_GetEntity(id); Entity entity = (Entity)Marshal::PtrToStructure((IntPtr)entityPtr, Entity::typeid); return entity; }
// exported functions extern "C" __declspec(dllexport) void StartApplication(HMODULE); void StartApplication(HMODULE win32Handle) { Program::SetExternalApplication(gcnew ExternalApplication(win32Handle)); }
// exported functions extern "C" __declspec(dllexport) void* GetEntity(int); void* GetEntity(int id) { Entity *entity = new Entity(); entity->id = id; entity->name = _bstr_t("I'm entity!").copy(); return entity; }
typedef void (__cdecl *StartApplicationFunc)(HMODULE); int _tmain(int argc, _TCHAR* argv[]) { HMODULE bridgeHandle = LoadLibrary(L"UnmanagedManaged.C++.dll"); StartApplicationFunc startApplication = (StartApplicationFunc)GetProcAddress(bridgeHandle, "StartApplication"); HMODULE handle = GetCurrentModule(); startApplication(handle); return 0; }
Source: https://habr.com/ru/post/131073/
All Articles