Передать строку в dll c

Обновлено: 07.07.2024

@jcmvbkbc Вы уж простите, но я Вам не чувак.
>класс string в dll С++
Из этой строчки вы поняли, что и dll и основное приложение написано на C++? Я понял, что dll написана на С++, а про основное приложение ничего не сказано. Это первое.

Второе. Тем не менее, даже, если речь шла только про С++, тут ничего не сказано про компиляторы. Это не будет работать (или скорее всего не будет работать) с разными компиляторами\версиями компилятора! Так что в любом случае Вы даете плохой совет.

Третье. Это уже мой совет автору. Используйте в dll только pod-типы. Внутри можно использовать все, что захотите, но снаружи должны быть видны только pod'ы. Это безопасно и универсально, избавит вас от головной боли в использовании библиотечки.

> я Вам не чувак
а было очень похоже, когда речь пошла про дельфи.

>> класс string в dll С++
> Из этой строчки вы поняли, что и dll и основное приложение написано на C++?
из этой строчки я понял, что dll пишется автором на C++. Основное приложение должно бы быть написано на С++ чтобы с лёгкостью передавать std::string куда-нибудь, иначе мы бы сначала увидели какой-нибудь другой вопрос, например, "как из дельфи передать в dll на С++ std::string".

> в любом случае Вы даете плохой совет
во-первых в моих ответах нет советов.
Во-вторых, не в любом же. В типичном случае использования одного компилятора всё будет работать нормально.

> Используйте в dll только pod-типы. Внутри можно использовать все, что захотите, но снаружи должны быть видны только pod'ы
вы бы тогда уж добавили, что функции видные снаружи должны быть хотя бы extern "C", а то ведь и mangling может быть разный, и конвенция вызова.


я Вам не чувак
а было очень похоже, когда речь пошла про дельфи.

Я, признаться, не улавливаю здесь совершенно никакой корреляции.

И Вы цепляетесь исключительно к моему упоминанию delphi, отводя на второй план мною указанное возможное различие компиляторов. Если уж Вы сочли мою догадку в использовании автором dll не из С++ глупой, почему свою догадку про

вы не находите таковой? В постановке вопроса про один компилятор не слова. Ну и ваш типичный случай - это парниковый вариант.

Основное приложение должно бы быть написано на С++ чтобы с лёгкостью передавать std::string куда-нибудь, иначе мы бы сначала увидели какой-нибудь другой вопрос

"Основное приложение должно бы быть написано на С++"
WTF? С чего бы это оно должно и как это вы поняли?

написано на С++ чтобы с лёгкостью передавать std::string куда-нибудь
вы бы тогда уж добавили, что функции видные снаружи должны быть хотя бы extern "C", а то ведь и mangling может быть разный, и конвенция вызова.

К счастью, все это было в моей ссылке выше, которую, конечно же, Вы прочитали? )

Я подытожу, спорить дальше смысла не вижу.
Если Вы(автор) только набиваете шишки, Вы можете пойти по такому пути. Когда кому-то еще потребуется использовать вашу библиотеку вы обязательно рано или поздно наткнетесь на проблемы.

Передача строк в dll и вывод на форму
Здравствуйте! Подскажите, пожалуйста, как правильно организовать передачу строк в dll!! вот есть у.

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

Передача данных в dll
Есть .dll: library dll; uses Windows, WinInet, SysUtils, TlHelp32, UrlMon, Dialogs; var .

Передача массива в dll
Не могли бы обьяснить как реализовать сабж?(возможно ссылку на теорию) Пробовал и в тупую.

Решение

Здесь проблема вот в чём. Вызывающая программа и DLL используют одно и тоже адресное пространство, поэтому в обмене данными можно применять указатели. Но вызывающую программу и DLL обслуживают два различных экземпляра менеджера памяти. И, соответственно, оба менеджера используют две раздельных "кучи" - т. е. две отдельные друг от друга области динамической памяти. Поэтому, если для некого объекта память была выделена, например, в DLL, потом указатель на него был передан в вызывающую программу, а затем, если вызывающая программа попытается осободить память из под этого объекта - то менеджер памяти вызывающей программы выполнит действия по особождению в неподконтрольном ему участке памяти - т. е. в области динамической памяти, которая обслуживается не им, а другим менеджером - связанным с DLL. Такие действия могут даже разрушить целостноть кучи, принадлежащей DLL.
---
Решать эту проблему можно поразному:
1. Использовать модуль ShareMem - этот модуль надо прописать самым первым в предложении Uses в модуле вызывающей программы и модуле DLL. Кроме этого вместе с приложением надо поставлять дополнительную DLL библиотеку: BORLNDMM.DLL. Эта библиотека, содержит альтернативный менеджер памяти Delphi.
Здесь могут быть, как раз, такие проблемы:
. но при выходе из программы всё равно выскакивает ошибка. Есть и другие альтернативные менеджеры - в инете можно поискать. Они возможно более стабильные. А может и нет.
2. Не использовать динамические типы и указатели. Это часто весьма неудобно.
---
3. Третий вариант - на мой взгляд наиболее удобный.
Идея вот в чём - те динамические объекты, которые создаёт менеджер памяти, связанный с DLL, пускай этот же менеджер памяти и уничтожает. Для этого просто в раздел экспорта поместим процедуру для удаления "собственных" объектов.
Делается, например так:
Код DLL:
Здесь в ProcStr() параметр aSize имеет двойное назначение - при вызове функции через него следует передать размер входной строки, а при возвращении управления в вызывающую программу, через этот же параметр возвращается размер выходной строки.
---
Примеры приведены для случая, когда:
type String = type AnsiString;
- например, для Delphi7.
Для Delphi 2009/2010 надо скорректировать программу - там:
type String = type WideString.
Соответственно, длина строки символов и размер будут иметь различное значение. И пр. А вот пример для слабенького уровня знаний. Dll + Программа Огромное спасибо всем ответам, всё достаточно развёрнуто и понятно, исходники оба рабочие, единственное поменял загрузку на динамическую. Отличный форум, отличные знатоки =) Функция возвращает значение, которое в вызывающем коде подставляется в том месте, где эта функция вызвана. Функция может быть элементом в выражении. Например:

Процедура не возвращает значение и не может участвовать в выражениях. Функции и процедуры могут иметь список параметров. Данные, переданные в подпрограмму через параметры, могут быть изменены. Изменения параметров отражаются в вызывающей программе, если эти параметры объявлены со спецификатором VAR. Таким образом, представленный выше код можно заменить на код с процедурой, в которой результат вычисления квадрата передаётся в вызывающий код через дополнительный параметр aRes:

Invalid pointer operation

у нас в проекте штук 20 DLL, строки передаются и боком и раком, и std::string, и CString, и по ссылке и по значению (зачастую для возвращаемого результата) и еще char* и даже char*& и т.д.

2 vdimas
Гм.
Хотелось бы посмотреть как это вы научились возвращать объекты из ф-ии.
У меня, например, не получилось. Никакие calling conversion не помогают.
[кусь. ]
Всему виной, по-видимому, разные менеджеры памяти для dll и exe. Если вызовы new и delete заменить на HeapCreate, HeapAlloc и HeapDestroy соотвественно, то все нормально прокатывает!

Гм, Гкхм, Кхе-кхе-а-а, уффф.
Знаешь, а exe и dll на одном и том же С++ написаны.

У меня однажды подобная проблема была, когда я в одном месте переопределил глобальный new, а в других ЗАБЫЛ. Если же использую или только по-умолчанию или везде свой менеджер, то ВСЕ РАБОТАЕТ!

Я бы сказал - давай исходники, поищу ВАШУ ошибку, но совершенно занят последнее время :)

проверь, все ли DLL и exe скомпилены с одной и той же опцией насчет линкования MFC.

Да нет, MFC тут не причем.
Но на всякий случай скажу - в опциях и того и другого проекта указано, что MFC не используется. Программа падает, когда менеджер памяти подчищает то, что было выделено. Это происходит на вызове ф-ии Rumtime _free_dbg, а точнее в _CrtIsValidHeapPointer, а еще точнее в HeapValidate.
Отсюда вывод, что по крайней мере по умолчанию в Visual C++ 6 и по крайней мере в дебагерной версии менеджеры памяти для dll и exe разные. Возможно их можно привести в соответствие.

Вызов HeapValidate выглядит так:
if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), TRUE))
return FALSE;
.
HeapValidate( _crtheap, 0, pHdr(pUserData) );// Брык.
pUserData - это указатель на то, что я удаляю по delete - вполне корректный указатель. До самого последнего момента *pUserData дает в отладчике именно то, что там должно быть.

Т.е. можно предположить, что текущий _crtheap не совпадает с тем, который использовался при выделении pUserData.

Если не лень читать привожу код DLL:

объект созданный одним манагером разрушается другим. Ты хоть думай прежде чем говорить. Это возможно только при одинаковых менеджерах памяти! Если в C это так, то да, но в общем случае это не так.
"Это всего-навсего переносимый вид. " это куда мы собрались что переносить? Это всего лишь правилльное решение не зависящее от приложеня от того на чем оно написано и прочее. Если всего этого не нужно. то я пережавал и объекты безо всяких заморочек, вот только вызвать эту dll могло приложение только при определенных условиях!

Странный ты, однако.
В том случае с контролеррами я тоже попросил ОБОСНОВАНИЙ, хотя бы одно. так и не услышал ничего из технической области. Если уж споришь, так спорь по-существу, приводи аргументы, а не охай.

У меня мыло и все остальное открыто как раз на тот случай, чтобы вещи азбучного характера не постить сюда. и мне вовсе не жалко (было) потратить 10 мин в аське, дабы кому-то ответить лично. Твой первый пост - полнейший бред, с т.з. С++, более того, он утверждает, что стандарты С++ отныне не работают. Я же утверждаю, что про С++ ты только в журналах читал, потому и предложил продолжить вне форума.

Я перехожу к C++ вот так:

Мой код C++ выглядит следующим образом:

и то, что возвращается с другой стороны, это:

В случае, если кто-то по той или иной причине не может его увидеть, stringArray[1] равно H, -, толстой линии, l и символу счастливого лица. Это явно не то, что я вкладываю.

Есть ли у кого-нибудь идея, где я могу ошибиться с этим? Я довольно долго бился головой об эту проблему и действительно мог бы воспользоваться некоторой помощью, так как мне кажется, что здесь мне не хватает чего-то действительно простого.

Edit: согласно предложению антиджона, я действительно изменил свой SetGrammarData, чтобы сделать копию строк, но я все еще сталкиваюсь с проблемой.

Теперь я заканчиваю с этим выводом:

Edit2: только что понял, что wchar_t похож на символ, а не на строку, не знаю, почему я думал, что он ведет себя как строка. Возвращаясь к чертежной доске, нужно выяснить, как лучше всего скопировать a wchar_t**., не имея такого опыта работы с C++, но я не думаю, что можно получить длину a wchar_t*, не передавая ее самому себе, но мне придется заглянуть в нее.

Edit3: наконец-то он заработал должным образом.

Вот что у меня получилось:

Edit4: думал, что он работает правильно, но ошибся. Я тестировал с exe, проходящим обратно к самому себе, но при прохождении через dll к другому exe ничего не проходило. Теперь у меня это работает:

1 ответ

Я создаю DLL в C++, он будет использоваться в проекте Delphi 7. Этот вопрос связан с этим , где я представляю две функции Validate и GetToken только для того, чтобы теперь они были сделаны в C++, а массив строк GetToken будет отправлен обратно в Delphi. Проблема в том, что я не знаю, как создать.

Пара возможных проблем здесь:

Похожие вопросы:

как передать строковый массив из C/C++ dll в vba (Excel) dll в Visual Studio dll не управляется, ATL и т. д. с уважением Энди

Я создаю DLL в C++, он будет использоваться в проекте Delphi 7. Этот вопрос связан с этим , где я представляю две функции Validate и GetToken только для того, чтобы теперь они были сделаны в C++, а.

Я написал базовую библиотеку C++, которая получает данные с сервера OPC UA и форматирует их в массив строк (char **). я подтвердил, что она работает автономно, но теперь я пытаюсь вызвать ее из.

Читайте также: