SafeArray aus VB in einer DLL redimensionieren und mit Daten füllen
-
Hi,
ich würde gerne ein Array aus Visual Basic an eine C DLL übergeben und dieses Array anschließend in der DLL redimensionieren und mit Daten füllen.
Momentan versuche ich es mit einem SafeArray, dieses SafeArray lege ich in VB an und übergebe es der DLL, darauf soll die DLL per API Funktion SafeArrayRedim() das Array auf eine bestimmte Größe bringen.
Allerdings gibt die SafeArrayRedim() Funktion nicht das gewünschte Ergebnis zurück: DISP_E_ARRAYISLOCKED
Ein zuvor ausgeführtes SafeArrayUnlock() gibt einen UNKNOWN ERROR zurück.
Option Explicit ' Dll Private Declare Function testDLL Lib "D:\SafeArray ermitteln - DLL\Debug\test.dll" (ByVal PointerToSafeArray As Long) As Long ' API Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long) 'Die Bounds für das SafeArray Private Type SAFEARRAYBOUND cElements As Long lLbound As Long End Type 'Das SafeArray, eindimensional Private Type SAFEARRAY1D cDims As Integer fFeatures As Integer cbElements As Long cLocks As Long pvData As Long Bounds(0 To 0) As SAFEARRAYBOUND End Type 'Ausgabe der Struktur Private Sub DisplaySafeArray(SA As SAFEARRAY1D) Dim H As String H = ".cDims = " & SA.cDims & vbCrLf H = H & ".fFeatures = " & SA.fFeatures & vbCrLf H = H & ".cbElements = " & SA.cbElements & vbCrLf H = H & ".cLocks = " & SA.cLocks & vbCrLf H = H & ".pvData = " & SA.pvData & vbCrLf H = H & ".Bounds(0).cElements = " & SA.Bounds(0).cElements & vbCrLf H = H & ".Bounds(0).lLbound = " & SA.Bounds(0).lLbound & vbCrLf Text1.Text = H End Sub Private Sub Form_Load() Dim lLoop As Long Dim MyArray(0) As Long Dim SafeArray As SAFEARRAY1D Dim PointerToPointer As Long Dim PointerToSafeArray As Long MyArray(0) = 42 'Ersten Zeiger ermitteln PointerToPointer = VarPtrArray(MyArray) 'Zweiten Zeiger auslesen Call CopyMemory(PointerToSafeArray, ByVal PointerToPointer, 4&) 'SafeArray in vorgegebene Strukur kopieren Call CopyMemory(SafeArray, ByVal PointerToSafeArray, Len(SafeArray)) ' DLL aufrufen Call testDLL(PointerToSafeArray) ' SafeArray Infos in VB anzeigen, darunter auch die Größe des Arrays Call DisplaySafeArray(SafeArray) For lLoop = 0 To UBound(MyArray) Text1.Text = Text1.Text & vbCrLf & "MyArray[" & lLoop & "] = " & MyArray(lLoop) Next lLoop End Sub
#include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } long __stdcall testDLL(SAFEARRAY* SafeArray) { HRESULT hresult; SAFEARRAYBOUND SafeArrayBound; SafeArrayBound.cElements = 10; SafeArrayBound.lLbound = 0; hresult = SafeArrayUnlock(SafeArray); if(FAILED(hresult) != 0) return 0; hresult = SafeArrayRedim(SafeArray, &SafeArrayBound); if(FAILED(hresult) != 0) return 0; return 1; }
-
SafeArrays sind zur Parametrisierung im Rahmen vom COM-Servern (DLL/EXE) gedacht. Die Übergabe als Parameter zwischen VB und konventionellenm C++ ist nicht beabsichtigt. Ich schliesse nicht aus das irgendwelche Hacks gibt. Wenn du jedoch zuverlässig Arrays zwischen VB und C++ übergeben willst verwende COM.
mfg JJ
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Wenn du jedoch zuverlässig Arrays zwischen VB und C++ übergeben willst verwende COM.
Ähm, hast du dafür vielleicht einen etwas konkreteren Vorschlag oder ein Tutorial parat?
-
Sowas z.B. müsste funktionieren (ungetestet zusammenghackt )
Declare Function ArrayUebergabe Lib "einedll.dll" (Byref FirstArrayElement As Long, Byval Length As Long) As Long Sub Main Dim EinLongArray(100) As Long Dim ret As Long ret = ArrayUebergabe( EinLongArray(0), 100 ) End Sub
extern "C" { __declspec(dllexport) long ArrayUebergabe(long* longArray, long length) } __declspec(dllexport) long ArrayUebergabe(long* longArray, long length) { for(int i = 0; i < length ; i++ ) { longArray[i] = 100; } return 0; }