Получить структуры из DLL без промежуточного кода - C#
Формулировка задачи:
Есть нативная длл. Для работы с длл необходимо написать программу на С# .
Имеется описание структур. там их много, укажу только две.
Пример С++:
Смотрим длл утилитой dumpbin
ordinal hint RVA name
3 0 00001A40 DllRegisterServer
4 1 00001B50 DllUnregisterServer
1 2 000125B4
И это работает
Вывод :
Device loaded.
IEasyDriver created.
Так вот вопрос :
Можно ли обойтись без промежуточного кода,
Сделать все силами С# без промежуточных ДЛЛ ?
#ifndef __IFactory_h__ #define __IFactory_h__ struct IFactory { virtual void* __stdcall Create(TCHAR*, void*) = 0; }; #endif
struct IEasyDriver { virtual unsigned __stdcall AddRef() = 0; virtual unsigned __stdcall Release() = 0; // return > 0 if success // return == 0 if operation not support // return < 0 if error, return IEASYDRIVER_ERROR_... code, call GetLastError() function for details virtual int __stdcall IO(ParametersBase*) = 0; };
IFactory* PCIFactory = NULL; IEasyDriver* m_pPCI = NULL; // здесь LoadLibrary(szPath); //Загружаем драйвер устройства PCIFactory = (IFactory*)GetProcAddress(m_hLib, szExportName); if(PCIFactory == 0)//Если устройство не загрузилось { cout<<"Can not load device"<<endl; return 0; } //Создаем интерфейс для работы с драйвером m_pPCI = (IEasyDriver*)PCIFactory->Create(_T("IEasyDriver"), 0); if(m_pPCI == 0)//Если интерфейс не создался { cout<<"Can not create IEasyDriver"<<endl; return 0; }
StaticFactory
2 3 000019D0 _DllMain@12 Сможем получить только указатель на структуру, больше ничего не экспортируется. Реализации методов у нас нет. Как быть? Написал промежуточный код на С++ ,точнее на C++/CLI для удобства, но не важно получилась дополнительная сборка.#include "IEasyDriver.h" #include "IFactory.h" #include "WrEasyDriver.h" #include "MeConvert.h" using namespace System; public ref class WrFactory { private: IFactory * pFactory; public: WrFactory(IFactory * _pFactory) { pFactory = _pFactory; } WrFactory(IntPtr _ptr) { pFactory = static_cast<IFactory *>(_ptr.ToPointer()); } WrFactory() { pFactory = 0; } public: static WrFactory^ PtrToFactory(IntPtr _ptr) { return gcnew WrFactory(_ptr); } WrEasyDriver^ Create( System::String^ InterfaceName, System::IntPtr pReserved) { if( !pFactory) return nullptr; char chInterfaceName[100]; MeConvert::ConvertStr(InterfaceName,chInterfaceName); IEasyDriver* pEasyDriver = static_cast<IEasyDriver*>( pFactory->Create(chInterfaceName,0)); return gcnew WrEasyDriver(pEasyDriver); } }; #pragma once #include "WrParametersBase.h" #include "IEasyDriver.h" using namespace System; public ref class WrEasyDriver { IEasyDriver* pEasydriver; public: WrEasyDriver(IntPtr _ptr) { pEasydriver = static_cast<IEasyDriver*>(_ptr.ToPointer()); } WrEasyDriver(IEasyDriver* _pEasydriver) { pEasydriver = _pEasydriver; } public: WrEasyDriver() { pEasydriver = 0; } static WrEasyDriver^ PtrToDriver(IntPtr _ptr) { return gcnew WrEasyDriver(_ptr); } public: unsigned AddRef() { if( ! pEasydriver ) return 0; return pEasydriver->AddRef(); } public: unsigned Release() { if( ! pEasydriver ) return 0; return pEasydriver->Release(); } // return > 0 if success // return == 0 if operation not support // return < 0 if error, return IEASYDRIVER_ERROR_... code, call GetLastError() function for details //virtual int __stdcall IO(ParametersBase*) = 0; public: int IO(IParametersBase^ _iParametersBase) { ParametersBase paramBase; paramBase.m_nType = _iParametersBase-> m_nType; paramBase.m_nSizeOf = _iParametersBase->m_nSizeOf; return pEasydriver->IO(¶mBase); } };
WrFactory PCIFactory = null; WrEasyDriver m_pPCI = null; IntPtr m_hLib; string szPath = "SampleDLL.dll"; string szExportName = "StaticFactory"; m_hLib = LoadLibrary(szPath); if (m_hLib == IntPtr.Zero) { Console.WriteLine("Can not load Library"); FreeLibrary(m_hLib); return; } IntPtr ptfactory = (IntPtr)GetProcAddress(m_hLib, szExportName); PCIFactory = WrFactory.PtrToFactory(ptfactory); if (PCIFactory == null)//Если устройство не загрузилось { Console.WriteLine("Can not load device"); FreeLibrary(m_hLib); return; } else Console.WriteLine("device loaded."); // // //Создаем интерфейс для работы с драйвером m_pPCI = (WrEasyDriver)PCIFactory.Create("IEasyDriver", IntPtr.Zero); if (m_pPCI == null)//Если интерфейс не создался { Console.WriteLine("Can not create IEasyDriver"); FreeLibrary(m_hLib); return; } else Console.WriteLine("IEasyDriver created.");
Решение задачи: «Получить структуры из DLL без промежуточного кода»
textual
Листинг программы
[ComImport, Guid("6981C3CD-1874-40E4-9B1F-E998171A9B7C")] class ProxyClass { } void Main() { var proxyClass = new ProxyClass(); var obj = (ISampleInterface)proxyClass; obj.SampleMethod(); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д