Получить структуры из 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();
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д