Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.07.17;
Скачать: [xml.tar.bz2];

Вниз

Вызов в Delphi функции из DLL, написанной на C++Builder   Найти похожие ветки 

 
Doid   (2003-07-02 16:37) [0]

Есть DLL-ка, написанная на Билдере. В ней есть такая экспортируемая функция
(файл rtb.cpp):

#inсludе <windows.h>
#inсludе "rtb_custom.h"
#inсludе "rtb.h"
...
const SUPPORTED_PROTOCOLS = 2;
...
typedef SProtocol *(PProtocols[SUPPORTED_PROTOCOLS]);
...
DWORD GetSupportedProtocols(SProtocol *SupProts, DWORD &dimSupProts)
{
...
}

Суть ее следующая: при вызове данная функция создает динамический массив поддерживаемых протоколов передачи данных SupProts, в dimSupProts пишет число поддерживаемых протоколов и передает все это хозяйство в вызвавшую ее клиентскую прогу, написанную на Делфи.
(файл rtb.h):

#ifndef _RTB_H
#define _RTB_H
#ifdef __DLL__
# define DLL_EI __declspec(dllexport)
#else
# define DLL_EI __declspec(dllimport)
#endif
...
extern "C" DWORD DLL_EI GetSupportedProtocols(SProtocol *SupProts, DWORD &dimSupProts);
...

В файле (rtb_custom.h) описана структура протокола:

#ifndef _RTB_CUSTOM_H
#define _RTB_CUSTOM_H
struct SProtocol {
short ID;
char* Name;
};
...

Вопрос: Как правильно описать структуру протокола и прототип функции (DLL-ка загружается статически) в Делфи?
Буду искренне признателен за ответ


 
jack128   (2003-07-02 17:09) [1]

PSProtocol = ^SProtocol;
SProtocol = record
id : smallint;
Name : Pchar;
end;

function GetSupportedProtocols(Protocols : PSProtocol; var ProtocolsCount) : DWORD; cdecl; external "mydll.dll" name "GetSupportedProtocols";

зы Насчет cdecl не уверен
pps Память не забуть выделять под массив перед вызовом функции




 
icWasya   (2003-07-02 17:21) [2]

>Суть ее следующая: при вызове данная функция создает динамический массив поддерживаемых протоколов передачи данных SupProts, в dimSupProts пишет число поддерживаемых протоколов и передает все это хозяйство в вызвавшую ее клиентскую прогу

при таком прототипе
DWORD GetSupportedProtocols(SProtocol *SupProts, DWORD &dimSupProts)

функция должна на входе получать уже созданный массив
или я не прав ?


 
jack128   (2003-07-02 17:33) [3]

описка
function GetSupportedProtocols(Protocols : PSProtocol; var ProtocolsCount : DWORD) : DWORD; cdecl; external "mydll.dll" name "GetSupportedProtocols";


 
Doid   (2003-07-02 17:40) [4]

Вообще-то она ( по задумке) должна создавать динамический массив. Почему? (Прошу прощения за небольшое уклонение от темы) Эта DLL-ка отвечает за взаимодействие клиентского приложения с ком-портом. В создаваемой версии будет поддерживаться 2 протокола . Если выпустить новую версию, в которой будет поддерживаться, скажем 4 протокола, то данная функция должна возвращать массив, состоящий из 4 элементов SProtocol. Надеюсь, что я понятно объяснил :).


 
jack128   (2003-07-02 18:06) [5]


> Doid © (02.07.03 17:40)

А кто в таком случае уничтожать массив(освобождать память) будет??
Проще сделать так, как это в апи делается
в DLL 2 функции
function GetSupportedProtocolsCount : DWORD - кол-во протоколов


function GetSupportedProtocols(Protocols : PSProtocol; MaxProtocolsCount : DWORD) : DWORD - кол-во возвращенных протоколов - эта функция не создает, а заполняет массив (максимал кол-во элементов в массиве - MaxProtocolsCount)??


 
Doid   (2003-07-02 19:02) [6]

//
Мне кажется, что возможны оба способа (Почему бы вызывающему приложению не уничтожать созданный в DLL массив?).

Хотя твоя, jack128, мысль - хорошая!

Разница в том, получается, где будет создаваться массив: в вызывающей проге или в DLL-ке. Однако, буду очень благодарен за обоснование выбора одного из двух представленных вариантов (сам впредь буду использовать и другим советовать как правильно писать проги, если конечно прийдется).


 
panov   (2003-07-02 19:15) [7]

Правило:
То, что динамически создается в DLL, должно в DLL-же и уничтожаться. И наоборот.


 
Doid   (2003-07-03 08:48) [8]

panov © (02.07.03 19:15)
Большое спасибо за данный совет.


 
Doid   (2003-07-03 09:05) [9]

Таким образом, все участники, если я правильно понял, сходятся на мысли, что вызывающая прога:
1) Вызывает что-то вроде GetSupportedProtocolsCount
2) Затем создает динамический массив с длиной, равной по полученному результату.
3) Вызывает GetSupportedProtocols(var Protocols : PSProtocol) (уже без длины)
4) DDL-ка, в свою очередь, заполняет этот массив данными, после чего вызывающая прога может использовать инфу на все 100% по своему усмотрению.
5) Прога, вдоволь наюзавшись, по необходимости уничтожит массив и все будет пучком.


 
Doid   (2003-07-03 15:27) [10]

Небольшая поправка:
В функции GetSupportedProtocols(var Protocols : PSProtocol) var не нужен. Работать не будет с ним.

Огромная благодарность всем, принимавшим участие в форуме. Спасибо за ваши советы и рекомендации. Все заработало как надо.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.07.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.01 c
1-55559
Mishenka
2003-07-06 23:52
2003.07.17
Изменение значения в SpinEdit...


14-55829
Centurion
2003-07-01 15:04
2003.07.17
DevExpress for Delphi 7


3-55415
andrew_kv
2003-06-24 08:50
2003.07.17
Есть соединение с SQL сервером через ADO


14-55722
r0n1n
2003-06-30 00:15
2003.07.17
Чат


14-55842
A0th
2003-06-27 23:30
2003.07.17
Антивирус





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский