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

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

10.10.2022, 07:10. Показов 875. Ответов 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
18250 / 14174 / 5366
Регистрация: 17.03.2014
Сообщений: 28,850
Записей в блоге: 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
18250 / 14174 / 5366
Регистрация: 17.03.2014
Сообщений: 28,850
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru