Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942

Получить структуры из DLL без промежуточного кода

04.08.2014, 08:17. Показов 2303. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть нативная длл. Для работы с длл необходимо написать программу на С# .
Имеется описание структур. там их много, укажу только две.
C++
1
2
3
4
5
6
7
#ifndef __IFactory_h__
#define __IFactory_h__
struct  IFactory
{
    virtual void* __stdcall Create(TCHAR*, void*) = 0;
};
#endif
C++
1
2
3
4
5
6
7
8
9
10
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;
};
Пример С++:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    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;
   }

Смотрим длл утилитой dumpbin

ordinal hint RVA name

3 0 00001A40 DllRegisterServer
4 1 00001B50 DllUnregisterServer
1 2 000125B4 StaticFactory
2 3 000019D0 _DllMain@12

Сможем получить только указатель на структуру, больше ничего не экспортируется.
Реализации методов у нас нет. Как быть?
Написал промежуточный код на С++ ,точнее на C++/CLI для удобства, но не важно
получилась дополнительная сборка.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#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);
    }
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 #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(&paramBase);
     }
 
};

И это работает

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
       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.");

Вывод :
Device loaded.
IEasyDriver created.

Так вот вопрос :

Можно ли обойтись без промежуточного кода,
Сделать все силами С# без промежуточных ДЛЛ ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.08.2014, 08:17
Ответы с готовыми решениями:

Получить post ответ картинку и вставить ее на лист excel без промежуточного сохранения на диск
Есть код отправки запрос и получения ответа, задача вставить картинку на лист excel без промежуточного сохранения на диск. Function...

Смысл промежуточного кода?
Добрый вечер. При написании транслятора возник вопрос: в чем смысл генерации промежуточного кода? Можно ли обойтись без этого? Сложные...

Использование dll без оригинального кода
Добрый день. Имею следующую проблему: Есть библиотека dll без оригинального кода. Открываю её ПЕ Експлорером вижу некоторые импорт и...

9
Эксперт Python
 Аватар для dondublon
4649 / 2069 / 366
Регистрация: 17.03.2012
Сообщений: 10,177
Записей в блоге: 6
04.08.2014, 11:32
Судя по использованию интерфейсов и DllRegisterServer, DllUnregisterServer, длл-ка ваша является COM-сборкой. Так её и импортируйте.
1
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
04.08.2014, 13:24  [ТС]
dondublon, это да, но интерфейсы в данном случае не имеют наследников.
Реализации их методов нет . Были бы производные классы , дело другое, в функции
возвращающую указатель на интерфейс подставил наследника И все .
Но наследников нет .
А такую штуку из С# сделать не получается
C#
1
IFactory factory = GetInterfase(...)
на основе интерфейсов нельзя порождать объекты.
0
Эксперт Python
 Аватар для dondublon
4649 / 2069 / 366
Регистрация: 17.03.2012
Сообщений: 10,177
Записей в блоге: 6
04.08.2014, 13:43
Не понял, в чём проблема. Ну нет классов, значит - напишите.
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
04.08.2014, 13:45  [ТС]
Что писать ? Где возьму реализацию. Она в длл спрятана.
В этом был мой вопрос.
0
Эксперт Python
 Аватар для dondublon
4649 / 2069 / 366
Регистрация: 17.03.2012
Сообщений: 10,177
Записей в блоге: 6
04.08.2014, 13:49
Точно не в курсе, там по хитрому через специальные фабрики это делается.
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
04.08.2014, 13:53  [ТС]
Вот копипаст с MSDN, чтоб понятно было . Есть производный класс.
Его можно описать и вызвать методы .
А В моем случае производных нет .
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface ISampleInterface
{
    void SampleMethod();
}
 
class ImplementationClass : ISampleInterface
{
    // Explicit interface member implementation: 
    void ISampleInterface.SampleMethod()
    {
        // Method implementation.
    }
 
    static void Main()
    {
        // Declare an interface instance.
        ISampleInterface obj = new ImplementationClass();
 
        // Call the member.
        obj.SampleMethod();
    }
}
Добавлено через 1 минуту
dondublon, ну проблему то решил. И написал как. Через промежуточный код.
Но интересно от него избавится.
0
 Аватар для Konctantin
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
04.08.2014, 14:23
C#
1
2
3
4
5
6
7
8
9
10
11
[ComImport, Guid("6981C3CD-1874-40E4-9B1F-E998171A9B7C")]
class ProxyClass
{
}
 
void Main()
{
    var proxyClass = new ProxyClass();
    var obj = (ISampleInterface)proxyClass;
    obj.SampleMethod();
}
1
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
04.08.2014, 14:41  [ТС]
Konctantin, спасибо попозже посмотрю что это .
0
 Аватар для Konctantin
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
04.08.2014, 15:44
Еще вот с этим поиграйтесь Activator.CreateComInstanceFrom
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.08.2014, 15:44
Помогаю со студенческими работами здесь

Передача структуры из программы на c# в dll на c++ и получение структуры из dll
В общем проблема в том, что при попытке передачи структуры созданной в c# в dll на c++ происходит событие pinvokestackimbalance Гуглил...

Загрузка своего кода в память другого процесса без использования dll
Привет всем! Никак не могу разобрать с тем как внедрять именно код в пямять другого процесса. С внедрением dll вроде как разобрался, а вот...

Сложение и вычитания двух hex чисел без промежуточного перехода в dec
Не могу сообразить алгоритм как сложить два числеа в hex формате без перехода в dec и не используя встроенные методы платформы. Например...

Как получить(передать) в работу только форму без кода?
Есть необходимость - получить передать на доработку только форму проекта delphi XE7 - тоесть надо сделать дизайн, расставить все по местам...

Создание .dll и присоеденение .dll к проекту путем непосредственного написания кода
Здравствуйте, дорогие форумчане! Я прекрасно знаю, как создавать и прикреплять к проекту .dll файлы при помощи опций компилятора в Visual...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru