Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 29
.NET 4.x

Передача строки между C# и С++ DLL

03.05.2023, 05:32. Показов 727. Ответов 4

Студворк — интернет-сервис помощи студентам
Здравствуйте! Не могу разобраться как правильно передавать строки между C++ и C#. Пытаюсь написать "обертку" для класса c++(dll) и использовать ее в c#.

На стороне c++ выглядит так:
dll на 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
class SomeClass {
public:
    const char* class_name = new char[15];
    SomeClass() { };
    ~SomeClass() {
        delete class_name;
    };
    void setName(const char* name) {
        this->class_name = name;
    }
    const char* getName() {
        return class_name;
    }
};
 
extern "C" __declspec(dllexport) void* _stdcall SomeClass_SomeClass() {
    auto handle = new SomeClass();
    return handle;
}
extern "C" __declspec(dllexport) void _stdcall SomeClass_SetName(SomeClass *target, const char* name) {
    target->setName(name);
}
extern "C" __declspec(dllexport) const char* SomeClass_GetName(SomeClass *target) {
    auto* name = target->getName();
    return name;
}

На C# вызываю так:
Класс c#

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Runtime.InteropServices;
 
namespace WraperCaller
{
    internal class SomeClass
    {
        [DllImport("C:\\Users\\MTK-mPC\\source\\repos\\WraperCaller\\x64\\Debug\\WraperTest.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "SomeClass_SomeClass")]
        static extern IntPtr SomeClass_SomeClass();
 
        [DllImport("C:\\Users\\MTK-mPC\\source\\repos\\WraperCaller\\x64\\Debug\\WraperTest.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "SomeClass_SetName")]
        static extern void SomeClass_SetName(IntPtr handle, string name);
 
        [DllImport("C:\\Users\\MTK-mPC\\source\\repos\\WraperCaller\\x64\\Debug\\WraperTest.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "SomeClass_GetName")]
        static extern string SomeClass_GetName(IntPtr handle);
        public IntPtr Handle { get; set; }
        public unsafe SomeClass() { Handle = SomeClass_SomeClass(); }
        public unsafe void SetName(string name) { SomeClass_SetName(Handle, name); }
        public unsafe string GetName() { return SomeClass_GetName(Handle);}
    }
}

Main C#

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
 
namespace WraperCaller
{
    internal class Main_class
    {
        static void Main()
        {
            var s = new SomeClass();
            s.SetName("test_name");
            var name2 = s.GetName();
 
        }
    }
}


Так вот на C# вызов метода SetName("test_name") вроде проходит нормально, через отладчик вижу что поле класса установилось вроде корректно (поменялся адрес поля класса с++), но при последующем вызове GetName() в поле с++ класса мусор, хотя handle класса тот же, адрес поля в памяти тот же, это сборщик мусора c# постарался? но ведь у меня вызов на стороне c# помечен как unsafe...
Что то я запутался, подскажите пожалуйста в какую сторону копать и понимание каких тем нужно подтянуть
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.05.2023, 05:32
Ответы с готовыми решениями:

Передача структуры данных между DLL-ками / DLL - EXE в байтовом виде, влияет ли выравнивание?
Here i go again :declare: Допустим есть исполняемый файл EXE и динамическая библиотека DLL. В DLL в хэдэре каком - каком - нибуть...

Передача строк между Dll между Exe
Подскажите алгоритм предачи строк между динамической библиотекой и исполняемым файлом. Мне нужно: 1) Пердать из программы в...

Передача значения между формами в dll проекте
Доброе время суток. Имеется проект DLL. В проекте имеется 2 формы. Как передать значение переменной из одной формы в другую форму...

4
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
03.05.2023, 06:12
Цитата Сообщение от Driver32 Посмотреть сообщение
это сборщик мусора c# постарался?
Скорее всего.
Цитата Сообщение от Driver32 Посмотреть сообщение
но ведь у меня вызов на стороне c# помечен как unsafe...
И как это должно помочь с данной проблемой?
Цитата Сообщение от Driver32 Посмотреть сообщение
подскажите пожалуйста в какую сторону копать
Делайте копию строки на стороне С++ при получении из C#.

Так же можно вот это вот
C++
1
const char* class_name = new char[15];
заменить на std::string (при создании копирование происходит автоматически), в getName добавить вызов .c_str() и тоже будет работать...
1
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 29
03.05.2023, 07:30  [ТС]
На счет сборщика мусора думал что он не трогает то что помечено контекстом unsafe

С копией разобрался, сделал поле типа std::string, теперь значение поля class_name сохраняется вплоть до вызова GetName, но если сделать так:
C++
1
2
3
4
extern "C" __declspec(dllexport) const char* SomeClass_GetName(SomeClass* target) {
    
    return target->getName().c_str();
}
то ругается на висячий указатель (C26815 Это висячий указатель, так как он указывает на временный экземпляр, который был уничтожен.).

А как бы это сделать что бы без копирования, на указателях. Ладно тут у меня строку передать, а если что-то обьемнее
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
03.05.2023, 07:41
Цитата Сообщение от Driver32 Посмотреть сообщение
то ругается на висячий указатель (C26815 Это висячий указатель, так как он указывает на временный экземпляр, который был уничтожен.).
Надо было в getName, а не в SomeClass_GetName это добавлять...
1
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 29
03.05.2023, 07:50  [ТС]
Все работает, спасибо, буду осмыслять
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.05.2023, 07:50
Помогаю со студенческими работами здесь

Передача строки в dll
событие в программе procedure TForm9.Button3Click(Sender: TObject); var dan:PChar; dan:='123'; //как передать в функцию...

Передача строки из CSV файла в DLL C++
Здравствуйте. Есть собственноручно написанная DLL на C++, которая принимает и обрабатывает строку: extern "C"...

Передача строки на внешний DLL файл
Привет форумчане! С помощью такого кода организовал вызов из DLL файла в форму. Проблема заключается в том что из DLL значение возвращает,...

Передача строки между формами
Здравствуйте. Имеется dataGridView1 на Form1 заполняемый таблицей Сотрудники (Код сотрудника, ФИО). Как мне передать КодСотрудника в...

Передача текстовой строки между UserControl и Классом
Не могли бы вы подсказать почему не выполняется код. Класс: class ClassLID { public static string sValue {...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через 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-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru