2015-07-06 2 views
4

Мы хотели бы поделиться ADOConnection через границу DLL (Delphi в Delphi на данный момент, хотя в ближайшем будущем также может быть C# для Delphi).Совместное использование ADO-соединения по границе DLL

Как мы хотели бы гибко вызывать DLL из C# в будущем, мы надеялись, что сможем определить вызов DLL с использованием _Connection в качестве параметра. Что-то вроде:

procedure DoStuff (ADOConnection: _Connection) 
var 
    InnerConnection: TADOConnection; 
begin 
    InnerConnection := TADOConnection.create(nil); 
    try 
    InnerConnection.ConnectionObject := ADOConnection; 
    DoMoreStuff(InnerConnection); 
    finally 
    InnerConnection.free; 
    end; 
end; 

К сожалению, код TADOConnection деструктор закрывает соединение передается в него, что является нежелательным побочным эффектом. Добавление

InnerConnection.ConnectionObject := nil 

до свободного ничего не делать, так как это пойманы

if Assigned(Value) = nil 

в TADOConnection.SetConnectionObject, что приводит к вызову ничего не делает.

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

Редакция: Для наглядности имя пользователя/пароль исходного объекта TADOConnection задается с помощью процедуры .Open, поэтому эти данные не содержатся в строке соединения (на самом деле, неправильное имя пользователя обычно сохраняется, так как это Имя, используемое для 'проверки соединения' в редакторе MS UDL)

+1

Просто мысль: делать у вас есть возможность передавать данные Ado в TClientDataSet? Причина, о которой я прошу, заключается в том, что данные CDS легко переносить через границы DLL в качестве варианта. – MartynA

+0

@TLama Объект Connection не освобожден, он просто закрыт –

+0

@MartynA возможно, но не без большой перестройки. Мы пытаемся сделать это как быстрый патч для извлечения существующего кода в DLL для работы с сторонними библиотеками, которые не будут компилироваться в более поздних версиях Delphi. Реструктуризация использования ClientDataset потребует много логики разделения по границе DLL –

ответ

0

Вы можете попробовать так:

type TInit_StFattDLL = procedure(var DataBase:TAdoConnection); 
    var Init_StFattDLL:TInit_StFattDll; 

вызывающий является:

Function ConnectDll():Boolean; 
var 
    handleDll:THandle; 

begin 
    handleDll := LoadLibrary('mydll.DLL'); 
    @Init_StFattDLL := GetProcAddress(handleDll , 'myConnectFunction'); 

     if @Init_StFattDLL <> nil then 
     begin 
      Init_StFattDLL(ADOConnection1); 
      result:=true; 
     end 
     else 
     result:=false; 
end; 

в DLL, положить следующее:

в файле проекта поставить экспорт:

Exports myConnectFunction; 

глобальный раздел:

var Database:TAdoConnection; 

экспортируемая процедура заключается в следующем:

procedure myConnectFunction(var MyDataBase:TAdoConnection);export; 
begin 
    Database:=MyDataBase; 
end 
+0

Разве это не просто передача объекта TADOConnection через границу DLL? Как я уже сказал в этом вопросе, это вариант, но делает результирующую dll Delphi-only. –

+0

Да, таким образом вы передаете указатель класса Adoconnection. Во всяком случае, извините. Мой ум перестал читать ваш вопрос в «Дельфи в Дельфи в данный момент»;) –