|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
01.02.2008, 15:42 | #1 |
Новичок
Джуниор
Регистрация: 01.02.2008
Сообщений: 2
|
Передача данных из VC++ DLL в Delphi App
Здравствуйте, программисты!
Помогите, пожалйста, решить проблему передачи данных между приложением Delphi 2007 и DLL MS Visual C++ 6 Идея такая, что Delphi App делает запрос DLLке, а та возвращает данные. Вот код C++ [I] #define EXPORTCALLstd extern "C" __declspec(dllexport) __stdcall typedef struct { int nLevel; const char* name; double fVal; const char* szVal; }ITEMDATA; const char* Names[10] = {"January","February","March","Apri l","May","June","July","August","Se ptember","October"}; double fVals[10] = {1.99,2.88,3.77,4.66,5.55,6.44,7.33 ,8.22,9.11,10.111}; const char* szVals[10] = {"A","B","C","D","E","F","G","H","I ","J"}; ... EXPORTCALLstd int GetDataCount() { return 10; } EXPORTCALLstd int SendItemData(int nIndex, PITEMDATA pItemData) { ITEMDATA ItData; if(nIndex > 9) nIndex = 9; ItData.fVal = fVals[nIndex]; ItData.name = Names[nIndex]; ItData.nLevel = nIndex; ItData.szVal = szVals[nIndex]; //тут вываливается 0xC0000005 (*ItemData).fVal = fVals[nIndex]; (*ItemData).name = (const char*)Names[nIndex]; return 0; } /* вариант со структурой EXPORTCALLstd int SendItemData(int nIndex, int* nLevel, char* name, double* fVal, char* szVal) { if(nIndex > 9) nIndex = 9; *nLevel = nIndex; *fVal = fVals[nIndex]; /* mx = strlen(Names[nIndex]); szVal = (char*)malloc(mx); for(i=0; i < mx; i++) { *szVal = Names[nIndex]; szVal++; } */ return 1; } */ EXPORTCALLstd int SendItemData(int nIndex, int* nLevel, char* name, double* fVal, char* szVal) { int j,mx; if(nIndex > 9) nIndex = 9; *nLevel = nIndex; *fVal = fVals[nIndex]; mx = strlen(Names[nIndex]); for(j=0; j < mx; j++) { *name = Names[nIndex][j]; name++; } name[j] = '\0'; mx = strlen(szVals[nIndex]); for(j=0; j < mx; j++) { *szVal = szVals[nIndex][j]; szVal++; } szVal[j] = '\0'; return 1; } Вариант с параметрами работает, но строковые значения криво возвращаются. Дежучник в Си показывает после вызова из Дельфи с nIndex = 0, что name = 'January', а в уже Дельфи после вызова name = ''anuary'#0#0#0#0#0#0#0#0#0'е'#8'яя і'#2#0#0#1#0#0#0#$E#0#0#0'*Ѓ¦'#0'шф '#$12#0'fгУwе'#8'яяf'#$B#$1C#0#$E#0 #0#0#0#0#0#0 #0#0#0#0#1#0#0#0'Lц'#$12#0'|'#$1E'D ' Вот код Delphi type PInteger = ^Integer; PDouble = ^Double; PTITEMDATA = ^TITEMDATA; TITEMDATA = record nLevel:integer; szName:ShortString; fVal:double; szVal:ShortString; end; TformMain = class(TForm) btRequestData: TButton; sgrData: TStringGrid; btChangeData: TButton; procedure FormCreate(Sender: TObject); procedure btRequestDataClick(Sender: TObject); private { Private declarations } public { Public declarations } CppFnGetDataitemsCnt: function: integer; stdcall; //CppFnGetItemData: function(nIndex:integer; ItemData:TITEMDATA):integer; CppFnGetItemData: function(nIndex:integer; nLevel:PInteger; Name:PChar; fVal:PDouble; szVal:PChar):integer; stdcall; end; procedure TformMain.FormCreate(Sender: TObject); var HLib:THandle; begin formMain := self; //загрузь HLib := LoadLibrary('..\CDT_CppDLL\Debug\CD T_CppDLL.dll'); if HLib < 32 then ShowMessage('Lib didn`t load') else begin CppFnGetDataItemsCnt := GetProcAddress(HLib,'_GetDataCount@ 0'); if(not Assigned(CppFnGetDataitemsCnt)) then ShowMessage('Didn`t find GetDataCount func in lib '); CppFnGetItemData := GetProcAddress(HLib,'_SendItemData@ 20'); if(not Assigned(CppFnGetItemData)) then ShowMessage('Didn`t find SendItemData func in lib '); end; end; procedure TformMain.btRequestDataClick(Sender : TObject); var i: integer; nDataCnt:integer; nLevel:integer; Name,szVal:ShortString; fVal:double; ItemData:TITEMDATA; begin //это работает отлично nDataCnt := CppFnGetDataItemsCnt; for i:=0 to (nDataCnt - 1) do begin nLevel := 333; Name := '_123_'; fVal := 25.52; szVal := '-321-'; //грамотно изменяет числовые значения, но строковые возвращает краказяблами CppFnGetItemData(i,@nLevel,@Name,@f Val,@szVal); { ItemData.nLevel := 999; ItemData.szName := 'start name'; ItemData.fVal := 9.99; ItemData.szVal := 'start val'; CppFnGetItemData(i,ItemData); } end; end; Такие вот дела. Не пойму, в чём проблемы. А главное, не знаю уже отлаженного решения передачи данных, в т.ч. строковых из СиПП ДЛЛ в Дельфи приложение. Подскажите решение, пожалуйста. А ещё лучше, если объясните суть проблемы, чтобы я мог сам понять как это всё делается и почему не делается. Спасибо! |
01.02.2008, 16:23 | #2 |
Новичок
Джуниор
Регистрация: 18.01.2008
Сообщений: 1,720
|
Вот здесь я не совсем понял, где определяется ItemData:
Код:
Вариант с параметрами работает, но строковые значения криво возвращаются. Дежучник в Си показывает после вызова из Дельфи с nIndex = 0, что name = 'January', а в уже Дельфи после вызова name = ''anuary'#0#0#0#0#0#0#0#0#0'е'#8'яя і'#2#0#0#1#0#0# 0#$E#0#0#0'*Ѓ¦'#0'шф'#$12#0'fгУwе'# 8'яяf'#$B#$1C#0 #$E#0#0#0#0#0#0#0 #0#0#0#0#1#0#0#0'Lц'#$12#0'|'#$1E'D ' однозначно проблема совместимости строк дельфи и строк C (которые оканчиваются нулем) Дальше пока не дошел еще.. |
05.02.2008, 10:53 | #3 | |
Новичок
Джуниор
Регистрация: 01.02.2008
Сообщений: 2
|
Цитата:
Действительно, представление ShortString в Delphi такое: 0ой символ - длина строки, остальные - содержимое без нулевого на конце. Просто поменял в Си коде: mx = strlen(Names[nIndex]); for(i=0; i < btStrLen; i++) { *name= Names[nIndex][i]; name++; } name[i] = '\0'; на btStrLen = (char)strlen(Names[nIndex]); *name = btStrLen; for(i=0; i < btStrLen; i++) { *(++name) = Names[nIndex][i]; } И всё работает! |
|
Опции темы | Поиск в этой теме |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Чат, передача данных | Патрон | Общие вопросы Delphi | 1 | 24.06.2008 09:15 |
Передача данных | Ivanich | JavaScript, Ajax | 1 | 29.04.2008 00:25 |
Передача данных на сервер с помощью Delphi | Арес | Работа с сетью в Delphi | 7 | 10.03.2008 13:29 |
Передача данных | ChipLink | Общие вопросы Delphi | 4 | 06.01.2008 11:28 |