powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / DLL Extern "C" string & char
6 сообщений из 6, страница 1 из 1
DLL Extern "C" string & char
    #34382091
dGrichine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ, подскажите... "сами мы не местные" (с) где-то в метро

Понадобилось создать DLL и подключить к своему приложению на Powerbuilder.
Мое приложение может вызывать функции из внешних ДЛЛ только с в нотации extern "C".

Создал две функции - см. код ниже (не пинайте сильно за код - только учусь)
Код рабочий, но насколько я понимаю в функции exp_replace_all необходимо освобождать память выделенную под переменные string - иначе ИМХО происходит утечка памяти.

Подскажите плиз как работать со строками эффективнее в данной постановке задачи?

P.S.
Использую компилятор MinGW + Code::Blocks


Код: plaintext
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.
...
#define EXPORT extern "C" __declspec (dllexport)
using namespace std;

EXPORT char* CALLBACK exp_replace_all(char* a_source, char* as_old, char* as_new) {
    string s = a_source;
    string f = as_old;
    string r = as_new;

    l_replace_all_case (s,f,r,false);

    return strdup(s.c_str());
}

void l_replace_all_case(string& as_s, string as_old, string as_new, bool ab_ignorecase ) {
    unsigned int li_found;
    string       ls_search = as_s;
    int          li_new_length = as_new.length();
    int          li_old_length = as_old.length();

    if (ab_ignorecase)
    {
        l_lower(ls_search);
        l_lower(as_old);
        }

    li_found = ls_search.find(as_old,  0 );

    while(li_found != string::npos)
    {
          as_s.replace(li_found, li_old_length, as_new);
          ls_search = as_s;
          if (ab_ignorecase) l_lower(ls_search);
          li_found = ls_search.find(as_old,li_found + li_new_length);
          }
   return ;
}

...
Рейтинг: 0 / 0
DLL Extern "C" string & char
    #34384909
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dGrichineСоздал две функции - см. код ниже (не пинайте сильно за код - только учусь)
1) пиши лучше на plain С, проще будет жить
2) PB требует stdcall функций, а по умолчанию делаются cdecl.
...
Рейтинг: 0 / 0
DLL Extern "C" string & char
    #34385649
dGrichine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
1) пиши лучше на plain С, проще будет жить


Да, тоже пришел к этому выводу - конвертация char* в string и наоброт не тривиальное дело, да при том что надо освобждать память при возвращении из функции...
два дня изучал различные форумы по данной теме - однозначного решения нет - такое ощущение, что его нет в принципе :)
даже сделал объект, который сам за собой очищает память, но при возврате из функции, он благополучно очищает и значение результата :) мрак...

вижу выход писать на чистом С
...
Рейтинг: 0 / 0
DLL Extern "C" string & char
    #34385760
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dGrichineДа, тоже пришел к этому выводу - конвертация char* в string и наоброт не тривиальное дело, да при том что надо освобждать память при возвращении из функции...
два дня изучал различные форумы по данной теме - однозначного решения нет - такое ощущение, что его нет в принципе :)Ну не такое уж и сложное на самом деле, просто учти что в классическом С++ нету такого примитивного типа данных как string. Это исправляется тем, что string реализуют во всех библиотеках классов. Но это в свою очередь, тянет за собой то, что с разными реализациями string надо работать по разному.... В общем проблема не столько сложная, сколько дурацкая :)

dGrichineдаже сделал объект, который сам за собой очищает память, но при возврате из функции, он благополучно очищает и значение результата :) мрак...А этот как раз нормально. Ты не можешь гарантировать что память выделеная (или перераспределеная) внутри dll будет доступной хосту. При работе с dll хост должен распределять память и отдавать в dll указатель на нее.

dGrichineвижу выход писать на чистом Сесли я правильно понял что ты хочешь сделать, то примерно так:
Делаешь ReplaceAll.c, а чтоб уж совсем не связываться ни с какими библиотеками, можно и вручную поиграться с указателями :)
Код: plaintext
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.
int __declspec(dllexport) __stdcall ReplaceAll(char *destination, unsigned int destination_size,
		char *source_string, char *search_for, char *replace_with) {
	unsigned int pos_dest, replacements_count;

	replacements_count =  0 ;
	pos_dest =  0 ;
	while((*source_string) && (pos_dest < destination_size)) {
		if( *source_string == *search_for ) {
			int pos_substring;
			pos_substring= 0 ;
			while(search_for[pos_substring]) {
				if( source_string[pos_substring] != search_for[pos_substring] ) {
					goto copy_source_to_destination;
				}
				pos_substring++;
			}

			source_string += pos_substring;
			pos_substring =  0 ;
			while((replace_with[pos_substring]) && (pos_dest < destination_size)) {
				destination[pos_dest++] = replace_with[pos_substring++];
			}
			replacements_count++;
		} else {
            copy_source_to_destination:   
			destination[pos_dest++] = *source_string;
			source_string++;
		}
	}
	destination[pos_dest] =  0 ;

	return replacements_count;
}
Обрати внимание, что никаких #include тут не нужно. Потом компилируешь и линкуешь:
Код: plaintext
1.
gcc -c ReplaceAll.c
gcc -shared -o StringFunctions.dll -Xlinker --kill-at ReplaceAll.o

Ну а в PB уже объявляешь:
Код: plaintext
1.
2.
3.
4.
5.
6.
public function integer ReplaceAll ( &
	  ref string Destination, &
	  UnsignedInteger DestinationLength, &
	  string Source, &
	  string SearchFor, &
	  string RepalceWith) &
  library "StringFunctions.dll" alias for "ReplaceAll"
и используешь:
Код: plaintext
1.
2.
3.
4.
5.
6.
string Dest
int RepCount

Dest = Space( 255 )
RepCount = ReplaceAll( Dest,  255 , "abcdefgh abcdfgh abcdefgh", "cdef", "123456" )

MessageBox(string(RepCount) + " substrings found", Dest)
...
Рейтинг: 0 / 0
DLL Extern "C" string & char
    #34387917
dGrichine
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо White Owl !
Буду изучать пример. Правда немного пугает
Код: plaintext
goto
, ну ничего, главное понять суть :)
...
Рейтинг: 0 / 0
DLL Extern "C" string & char
    #34387965
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dGrichineСпасибо White Owl !
Буду изучать пример. Правда немного пугает
Код: plaintext
goto
, ну ничего, главное понять суть :)Не надо его пугаться, оно не кусается. А производительность повышает.
Goto вещь удобная и полезная, в разумных пределах конечно.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / DLL Extern "C" string & char
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]