![]() |
Delphi Interface in VB.NET verwenden
Hallo zusammen,
ich habe ein Problem mit einem Interface welches in VB.NET für eine Website (ASPX?! gedöns oder so) verwendet werden soll. Naja auf jeden Fall haben wir für unsere Windows Anwendungen ein Datenbank Treiber System entwickelt welches auch einwandfrei läuft. So nun soll unsere Webabteilung aber noch eine Anbindung zu unserem System bauen, und daher der Gedanke das sie die schon vorhandenen Lösungen (primär die Datenbank Anbindung) nutzen. Jetzt aber zum Technischen ;) Ein paar Exporte der DLL:
Delphi-Quellcode:
Das Interface welches von CreateConnection zurück geliefert wird:
function SetPDOHivePath(Path: WideString): Boolean; stdcall;
function CreateConnection(DriverID: WideString): IphDatabaseConnection; stdcall; function RegisterDatabaseDriver(Name: WideString): Boolean; stdcall; function CreateDatabaseObject(PDOName, ObjectName: WideString; Connection: IphDatabaseConnection): IphDatabaseObject; stdcall;
Delphi-Quellcode:
Und noch die CreateConnection funktion selbst:
type
IphDatabaseConnection = interface(IInterface) ['{3DDA5E0F-1BDD-415C-9F62-F8B5300562E5}'] function GetHost: WideString; stdcall; procedure SetHost(Host: WideString); stdcall; function GetPort: Integer; stdcall; procedure SetPort(Port: Integer); stdcall; function GetUsername: WideString; stdcall; procedure SetUsername(Username: WideString); stdcall; function GetPassword: WideString; stdcall; procedure SetPassword(Password: WideString); stdcall; function GetDatabase: WideString; stdcall; procedure SetDatabase(Database: WideString); stdcall; (snip, wird sonst zuviel) end;
Delphi-Quellcode:
Die Importe in VB.NET:
function CreateConnection(DriverID: WideString): IphDatabaseConnection; stdcall;
var Driver: TphDatabaseDriver; begin // Zeile 386 Result:=nil; Driver:=TphDataDriverCore.Initialize.GetDriverByID(DriverID); if Assigned(Driver) then begin Result:=Driver.GetDriverInstance; end; end;
Code:
Das Interface in VB.NET:
Declare Unicode Function SetPDOHivePath Lib "phData.dll" Alias "SetPDOHivePath" (<MarshalAs(UnmanagedType.BStr)> ByVal Path As String) As Boolean
Declare Unicode Function CreateConnection Lib "phData.dll" Alias "CreateConnection" (<MarshalAs(UnmanagedType.BStr)> ByVal DriverID As String) As IphDatabaseConnection Declare Unicode Function RegisterDatabaseDriver Lib "phData.dll" Alias "RegisterDatabaseDriver" (<MarshalAs(UnmanagedType.BStr)> ByVal Name As String) As Boolean Declare Unicode Function CreateDatabaseObject Lib "phData.dll" Alias "CreateDatabaseObject" (<MarshalAs(UnmanagedType.BStr)> ByVal PDOName As String, <MarshalAs(UnmanagedType.BStr)> ByVal ObjectName As String, ByVal Connection As IphDatabaseConnection) As IphDatabaseObject
Code:
Der test Aufruf in VB.NET:
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("3DDA5E0F-1BDD-415C-9F62-F8B5300562E5")> _
Public Interface IphDatabaseConnection Function GetHost() As <MarshalAs(UnmanagedType.BStr)>String Sub SetHost(<MarshalAs(UnmanagedType.BStr)> ByVal Host As String) Function GetPort() As Integer Sub SetPort(ByVal Port As Integer) Function GetUsername() As <MarshalAs(UnmanagedType.BStr)> String Sub SetUsername(<MarshalAs(UnmanagedType.BStr)> ByVal Username As String) Function GetPassword() As <MarshalAs(UnmanagedType.BStr)> String Sub SetPassword(<MarshalAs(UnmanagedType.BStr)> ByVal Password As String) Function GetDatabase() As <MarshalAs(UnmanagedType.BStr)> String Sub SetDatabase(<MarshalAs(UnmanagedType.BStr)> ByVal Database As String) (snip, wird sonst zuviel) End Interface
Code:
Bis zum aufruf von "CreateConnection" funktioniert alles soweit, nur hier kracht es dann.
SetPDOHivePath("C:\ObjectFiles\")
If RegisterDatabaseDriver("phDataMSSQL.dll") Then Dim Connection As IphDatabaseConnection = CreateConnection("driverid") Connection.SetHost("dbhost") Connection.SetPort(12345) Connection.SetDatabase("blubb") Connection.SetUsername("bla") Connection.SetPassword("foo") Dim DbObject As IphDatabaseObject = CreateDatabaseObject("objfile", "objname", Connection) DbObject.ExecuteQuery() ShowDebugWindow() End If EurekaLog meldet aus der DLL ein EOutOfMemory Error, und danach verabschiedet sich die VB-Anwendung komplett.
Code:
Der Callstack:
Exception:
------------------------------------------------------------------------- 2.1 Date : Thu, 2 Jul 2009 12:33:15 +0200 2.2 Address : 04BEDC75 2.3 Module Name : phData.dll 2.4 Module Version: 1.0.7.7 2.5 Type : EOutOfMemory 2.6 Message : Out of memory. 2.7 ID : 31D3 2.8 Count : 1 2.9 Status : New 2.10 Note :
Code:
Ich hab schon alles durch debugged, umgestellt, getestet und etc pp...
------------------------------------------------------------------------------------------------
|Address |Module |Unit |Class|Procedure/Method |Line | ------------------------------------------------------------------------------------------------ |*Exception Thread: ID=3996; Priority=0; Class=; [Main] | |----------------------------------------------------------------------------------------------| |04BEDC75|phData.dll |phDataMain.pas | |CreateConnection |386[0] | |04AA309A|phData.dll |system.pas | |ErrorAt |3291[3] | |04AA64DC|phData.dll |system.pas | |_WStrAddRef |14739[1]| |04BEDC75|phData.dll |phDataMain.pas | |CreateConnection |386[0] | |7E368A0B|USER32.dll | | |DispatchMessageW | | |78144FB0|MSVCR80.dll | | |memcpy | | |781458E6|MSVCR80.dll | | |memcmp | | |7C91D348|ntdll.dll | | |NtFlushInstructionCache | | |7C8355FE|KERNEL32.dll| | |FlushInstructionCache | | |77E5602D|RPCRT4.dll | | |NdrTypeFlags | | |7C9111DD|ntdll.dll | | |RtlDeactivateActivationContextUnsafeFast| | |7C9110E0|ntdll.dll | | |RtlLeaveCriticalSection | | |7C91DE98|ntdll.dll | | |ZwTestAlert | | |7C91D068|ntdll.dll | | |NtContinue | | |7C91D05E|ntdll.dll | | |NtContinue | | |7C91E45A|ntdll.dll | | |KiUserApcDispatcher | | ------------------------------------------------------------------------------------------------ Das einzige was funktionierte war wenn ich CreateConnection auf einen Primitiven Datentypen als Rückgabewert umstellte. Eine Vermutung war noch das es am WideString liegen kann und hab es dann mit PChar getestet, aber dasselbe. Ich hab echt keine Idee mehr :( Grüße, Daniel |
Re: Delphi Interface in VB.NET verwenden
Frage 1:
warum habt ihr eine "normale" DLL gebaut und nicht eine ActiveX-DLL? Eine ActiveX-DLL hat intern schon die Unterstützung durch Class factories und enthält eine TLB als Resource. Sie exportiert die Funktionen DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnregisterServer (daran erkennt man eine ActiveX-DLL). Importieren einer ActiveX-DLL geht in VB.NET mit wenigen Mausklicks. => Empfehlung: Umbauen auf eine ActiveX-DLL Frage 2: warum leitet ihr eure Interfaces nicht von IDispatch ab? Dies hat den großen Vorteil, dass alle Methoden auch aus einer Scriptsprache wie z.B. VB-Script angesteuert werden können. => Empfehlung: ActiveX-DLL mit Automatisierungsobjekten Das Verwenden in einer anderen Programmiersprache ist dann ganz einfach. Die Importe in VB.NET gehen dann vollautomatisch und fehlerfrei. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz