2017-06-19 1 views
-1

iteriert werden kann. Genau wie die Frage sagt. Ich möchte in der Lage sein, eine Reihe von Strings in einigen VBA-Code zu machen, in diesem Code möchte ich ihnen eine gewisse Länge geben. Dann, wie würde ich sie in eine C++ - DLL übergeben, in der DLL möchte ich eine Zeichenfolge in jedem Element speichern und diese Elemente von der VBA später zugänglich machen. Ich habe dies bereits für eine einzelne Zeichenfolge und für ein Doppel-Array wie folgt getan.Wie erstellt man ein Array von Strings in VBA/Excel und sendet es an eine C++ - DLL, so dass es durch in der DLL

Dim myStr As String * sizeConst 

Dim dataArray() As Double 
ReDim dataArray(0 To (arrayLength - 1)) As Double 

Anschließend übergibt sie an eine DLL aus der VBA.

Public Declare Function myFunc _ 
Lib "PathToDLL.dll" _ 
(myStr As String, ByVal sizeConst As Integer, dataArray As Double, ByVal arrayLength As Long) As Long 

Dann in der DLL kann ich jedes Element in der Doppel-Array durchlaufen. Ich weiß jedoch nicht, wie man das für ein String-Array macht. Ich bin nicht sicher über die tatsächliche Speichergröße der Strings, die ich von der VBA übergeben würde, wären sie von der Größe sizeConst + 1? Ich muss das wissen, um zu wissen, wie viel ich erhöhen sollte, um zum nächsten String-Element zu gelangen. Kann mir jemand zeigen, wie man ein String-Array in VBA mit einer konstanten Länge für jedes Element deklariert. Dann wie dieses Array an die DLL übergeben wird und wie das nächste Element im String-Array in der DLL inkrementiert wird.

+0

Vielen Dank für meine Antwort.Wenn die Antwort auf die Frage: "Wie erstellt man ein Array von Strings mit fester Größe?" Nicht Ihren Kriterien entspricht, müssen Sie genauer sein und die richtigen Details zu Ihrem Problem angeben. –

+0

@MaciejLos Der wichtige Teil ist "Dann, wie würde ich sie in eine C++ DLL übergeben". Weitere Informationen finden Sie unter https://stackoverflow.com/questions/44396538/vba-excel-and-c-dll-specifical-problems-with-strings#comment76262029_44396538. – GSerg

+0

@GSerg, Dies ist der zweite Teil der Frage. Ich habe diese Information zur Verfügung gestellt: 'Beachten Sie, dass Ihre DLL als Eingabe erwartet ** myStr As String **, nicht ein Array von Strings, wegen der Funktionsdeklaration. Der Trick ist die Fähigkeit, eine Frage zu stellen! –

Antwort

1

Wenn Sie arr() as string in einer Declare d Funktion deklarieren, wird VB aus senden Sie eine LPSAFEARRAY* (ein Doppelzeiger, SAFEARRAY**), bestehend aus BSTR s (FADF_BSTR | FADF_HAVEVARTYPE). Das heißt, die conversion to LPSTR wird nicht ausgeführt.

Auf der C++ Seite würden Sie den Parameter als LPSAFEARRAY* deklarieren und die SafeArray* family of functions verwenden, um die Daten zu manipulieren.

Beachten Sie, dass Sie für das Freigeben von BSTR s verantwortlich sind, die Sie ersetzen werden, wenn Sie sie ersetzen werden.

Sie erhalten alle Informationen über die Array-Größe und Abmessungen von der LPSAFEARRAY, und jede BSTR speichert ihre String-Länge.


Gleiche passiert, wenn Sie arr() as string * some_length erklären, aber dieses Mal die SAFEARRAY wird nur von FADF_HAVEVARTYPE sein und SafeArrayGetVartype wird VT_ERROR zurück. Jedes Element des sicheren Arrays ist ein vorab zugewiesener Blob von some_length breiten Zeichen (some_length * 2 Byte), wobei kein Null-Terminator oder eine String-Länge separat gespeichert ist. Es ist sogar noch einfacher, mit ihm zu arbeiten, da es vorab zugewiesen ist, Sie können einfach den vorhandenen Speicher jedes Elements füllen.


Wenn Sie nur Zeichenkette verwenden sind, ohne feste Länge, man könnte sich auch auf die gleiche Art und Weise übergeben Sie die Zeiger sind vorbei zu verdoppeln: auf der C

declare function myFunc ... (byval strings as longptr, byval count as long) 
dim s() as string 
redim s(1 to 5) 

myFunc varptr(s(lbound(s))), ubound(s) - lbound(s) + 1 

Dann ++ Seite würden Sie BSTR* der ersten Zeichenfolge erhalten, und um zur nächsten Zeichenfolge fortzuschreiten, würden Sie 1 dazu hinzufügen, wie Sie normalerweise mit Zeigermathematik tun würden. Sie müssen die Anzahl der Elemente als separaten Parameter übergeben, um zu wissen, wie viele Strings vorhanden sind.

Dies funktioniert nicht für Zeichenfolgen fester Länge.

+0

Danke GSerg. Ich denke, ich werde einfach das Beispiel ohne feste Länge verwenden. Wie kommt es, dass der Typ auf der C++ - Seite LPWSTR und nicht ein Zeiger auf den ersten BSTR wäre, wäre da nicht zusätzlicher Speicher von den anderen BSTR-Elementen (der Speicher, der die Größe speichert), dem ich ausweichen müsste? –

+0

Ich möchte noch einmal betonen, wie dankbar ich bin von der Hilfe, die Sie mir in meinem vorherigen Post und diesem auch geben. –

+0

@AlexWardlow Ich bin es gewohnt, es 'LPWSTR' zu nennen, weil das meistens auf der C++ Seite passiert. Ja, die Zeiger werden auch 'BSTR *' sein. Sie müssen nichts ausweichen, weil so "BSTR" entworfen wird und die String-Daten (im Gegensatz zu String-Zeigern) nicht nacheinander in einem fortlaufenden Speicherblock gespeichert werden. – GSerg

Verwandte Themen