Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 29.09.2022
Сообщений: 12

Динамическое подключение библиотеки DLL (написанной на C++)

10.10.2022, 07:10. Показов 937. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!

Мне необходима помощь в следующем. Мне нужно с датчика ИВТМ 7-М получить данные. Для него создана разработчиком библиотека DLL (EksisExchange.dll), которая написана на C++ (эта библиотека есть здесь в самом начале страницы https://www.eksis.ru/technical... -protocol/). Пытался ее добавлять через ссылку, но не получается. Вылизит ошибка. Поэтому как то необходимо использовать ее динамически. На C++ всё работает (код ниже, его скинул разработчик, но к сожалению у него нет такого на C#, а в C# переписать его не получается). Как бы это сделать есть ли у кого идеи?

Рабочий код C++, который выдает значение температуры:

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
#include "windows.h"
#include <iostream>
#include <stdlib.h>
 
bool(__stdcall* EKSIS_USB_Read)(const char*, char, DWORD, BYTE*, WORD);
HINSTANCE hDLL;
 
int main()
{
    const char* aTechNum = "10115664"; //10134541
    char aMem = 'R';
    DWORD aAddr = 0x0;
    BYTE aData[254];
    WORD aCount = 4;
    float Meas;
        
    hDLL = LoadLibraryA("C:\\Users\\maska\\source\\repos\\ConsoleApplication1\\Debug\\EksisExchange.dll");
    if (NULL == hDLL)
    {
        std::cout << "Error DLL";
    }
    else
    {
        EKSIS_USB_Read = (bool(__stdcall*)(const char*, char, DWORD, BYTE*, WORD))GetProcAddress(hDLL, "EKSIS_USB_Read");
 
        if (EKSIS_USB_Read(aTechNum, aMem, aAddr, &aData[0], aCount))
        {
            Meas = *(float*)(aData);
            std::cout << "Success\n" << " Output = " << Meas << "\n";
        }
        else
        {
            std::cout << "Error Output";
        }
        
        FreeLibrary(hDLL);
    }
    return 0;
}
Код который я пытался реализовать на C#:

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Runtime.InteropServices;
 
 
namespace ConsoleApp2
{
    class Program
    {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate bool EKSIS_USB_Read(string TechNum, char Mem, uint Addr, byte Data, ushort Count);
 
        static void Main(string[] args)
        {
            string aTechNum = "10115664";
            char aMem = 'R';
            uint aAddr = 0x0;
            byte[] aData = new byte[254];
            ushort aCount = 4;
            float Measuring;
 
            IntPtr hDLL = NativeMethods.LoadLibrary(@"C:\\Users\\maska\\source\\repos\\ConsoleApplication1\\Debug\\EksisExchange.dll");
            
            if (hDLL == null)
            {
                Console.WriteLine("Error!");
            }
            else
            {
                Console.WriteLine("Good");
            }
            
            IntPtr ProcAddr = NativeMethods.GetProcAddress(hDLL, "EKSIS_USB_Read");
            
            if (ProcAddr == null)
            {
                Console.WriteLine("Error!");
            }
            else
            {
                Console.WriteLine("Good");
            }
            
            EKSIS_USB_Read eksis_usb_read = (EKSIS_USB_Read)Marshal.GetDelegateForFunctionPointer(ProcAddr, typeof(EKSIS_USB_Read));    /* Здесь появляется ошибка System.ArgumentNullException: "Значение не может быть неопределенным.
Имя параметра: ptr" */
 
            bool result = eksis_usb_read(aTechNum, aMem, aAddr, aData[0], aCount);
            
            if (hDLL != null)
            {
                if (result)
                {
                    Measuring = Convert.ToSingle(aData);
                    Console.WriteLine("Success\n" + " Output = " + Measuring + "\n");
                }
                else
                {
                    Console.WriteLine("Error Output");
                }
            }
            else Console.WriteLine("No DLL");
            
            NativeMethods.FreeLibrary(hDLL);
 
            Console.ReadKey();
        }
    }
 
    static class NativeMethods
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);
 
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
 
        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
    }
}
Реализовать C# код пытался по следующему примеру: https://learn.microsoft.com/en... rom-net-c/.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.10.2022, 07:10
Ответы с готовыми решениями:

Динамическое подключение библиотеки, связанной с другой DLL
Всем привет! Вобщем проблемка такая: я пытаюсь создать объект класса который определен в другой длл которая и загружается соответственно...

Подключение библиотеки, написанной на C++
Здравствуйте. Пытаюсь подключить свою dll.dll написанную на С++. Подключаю на C#. Это читал: ...

Подключение к проекту и работа с Dll, написанной на C++
привет. надо вызвать функцию с c++ dll в программу с#. в с++ функции обязательно надо использовать тип string. Вопрос! Как в шарп вытащить...

5
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18296 / 14220 / 5368
Регистрация: 17.03.2014
Сообщений: 28,896
Записей в блоге: 1
10.10.2022, 10:41
Shadow1447, не думаю что здесь нужна динамическая загрузка. По идее p/invoke должен справиться.
0
0 / 0 / 0
Регистрация: 29.09.2022
Сообщений: 12
10.10.2022, 12:11  [ТС]
OwenGlendower, я попробовал использовать P/Invoke, но результат не очевидный. Выдает ошибку, которую исправить не получается. Эта ошибка в 22 строчке

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
using System;
using System.Runtime.InteropServices;
 
namespace TryToConnectIVTM
{
    internal class Program
    {
        public const string EksisDLL = @"C:\\Users\\maska\\source\\repos\\ConsoleApplication1\\Debug\\EksisExchange.dll";
 
        [DllImport(EksisDLL, CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern bool EKSIS_USB_Read(string aTechNum, char aMem, uint aAddr, byte aData, ushort aCount);
 
        static void Main(string[] args)
        {
            string TechNum = "10115664";
            char Mem = 'R';
            uint Addr = 0x0;
            byte[] Data = new byte[254];
            ushort Count = 4;
            double Measuring;
 
            if(EKSIS_USB_Read(TechNum, Mem, Addr, Data[0], Count))
            {
                Measuring = Convert.ToDouble(Data);
 
                Console.WriteLine("Success!\n" + "Result: " + Measuring);
            }
            else
            {
                Console.WriteLine("Error!");
            }
 
            Console.ReadKey();
        }
    }
}
Миниатюры
Динамическое подключение библиотеки DLL (написанной на C++)  
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
10.10.2022, 12:34
C#
1
2
[DllImport(EksisDLL, CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool EKSIS_USB_Read(string aTechNum, byte aMem, uint aAddr, ref byte aData, ushort aCount);
или
C#
1
2
[DllImport(EksisDLL, CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool EKSIS_USB_Read(string aTechNum, byte aMem, uint aAddr, byte[] aData, ushort aCount);
что-то такое должно быть...
1
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18296 / 14220 / 5368
Регистрация: 17.03.2014
Сообщений: 28,896
Записей в блоге: 1
10.10.2022, 12:57
Shadow1447, тип аргумента aData неверный. Someone007, уже привел исправление. И я бы еще явно указал соглашение о вызове StdCall в атрибуте DllImport.
0
0 / 0 / 0
Регистрация: 29.09.2022
Сообщений: 12
10.10.2022, 13:49  [ТС]
Someone007, OwenGlendower, спасибо вам огромное за помощь!) Всё получилось и работает как на C++. Оставлю тут рабочий код, если кому нужно будет.

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
using System;
using System.Runtime.InteropServices;
 
namespace TryToConnectIVTM
{
    internal class Program
    {
        public const string EksisDLL = @"C:\\Users\\maska\\source\\repos\\ConsoleApplication1\\Debug\\EksisExchange.dll";
 
        [DllImport(EksisDLL, CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EKSIS_USB_Read(string aTechNum, char aMem, uint aAddr, byte[] aData, ushort aCount);
 
        static void Main(string[] args)
        {
            string TechNum = "10115664";
            char Mem = 'R';
            uint Addr = 0x0;
            byte[] Data = new byte[254];
            ushort Count = 4;
            float Measuring;
 
            if(EKSIS_USB_Read(TechNum, Mem, Addr, Data, Count))
            {
                Measuring = BitConverter.ToSingle(Data, 0);
 
                Console.WriteLine("Success!\n" + "Result: " + Measuring);
            }
            else
            {
                Console.WriteLine("Error!");
            }
 
            Console.ReadKey();
        }
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.10.2022, 13:49
Помогаю со студенческими работами здесь

Подключение библиотеки DLL написанной на Си к проекту VB.NET
Мне нужен подробный пример написания библиотеки на Си и ее подключения к проекту VB.NET. Ссылку типа этой...

Чтение dll библиотеки написанной на C++ Builder 5 в C#
VS 2010. Казалось бы простой процесс чтения dll созданной в C++ Builder 5 выдаёт в C# неожиданности. Если вычислить при...

Подключение библиотеки, написанной на VS в других языках программирования
Существует ли возможность написать на VS такую dll - библиотеку, которую можно было бы использовать на языках программирования без...

Подключение к проекту DLL, написанной на Си
Требуется добраться до функций реализованных в dll, написанной на сишке. using System.Runtime.InteropServices; Далее в...

Подключение DLL, написанной на Delphi
Здравствуйте, помогите пожалуйста подключить Delphi dll к проекту c#. Вот сама dll library Project4; uses System.SysUtils, ...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru