如何在VBA / Excel中创建一个字符串数组,并将其发送到C ++ DLL,以便可以通过DLL [英] How to create an array of strings in VBA/Excel and send it to a C++ DLL so that it can be itterated through in the DLL

查看:652
本文介绍了如何在VBA / Excel中创建一个字符串数组,并将其发送到C ++ DLL,以便可以通过DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如问题所在。我想要在一些VBA代码中创建一个字符串数组,在这段代码中,我想让它们有一定的长度。那么我将如何将它们传递给C ++ DLL,在DLL中,我想在每个元素中存储一个字符串,并使这些元素从VBA afterwords中访问。我已经做了一个单一的字符串和一个双数组如下。

  Dim myStr As String * sizeConst 

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

然后将其从VBA中传递到DLL。

 公共声明函数myFunc _ 
LibPathToDLL.dll_
(myStr As String,ByVal sizeConst As Integer,dataArray As Double,ByVal arrayLength As Long)As Long

然后在DLL中我可以跨越双阵列中的每个元素。但是我不知道如何做一个字符串数组。我不确定从VBA传入的字符串的实际内存大小是否大小为sizeConst + 1?我需要知道这一点,知道我应该增加多少以获得下一个字符串元素。有人可以告诉我如何在VBA中为每个元素定义一个长度不等的字符串数组。然后如何将该数组传递给DLL,以及如何递增到DLL中的字符串数组中的下一个元素。

解决方案

当您在 Declare d函数中声明 arr()作为字符串时,VB将发出一个 LPSAFEARRAY * (双指针 SAFEARRAY ** )由 BSTR FADF_BSTR | FADF_HAVEVARTYPE )。也就是说,转换为 LPSTR 将不会执行。



在C ++方面,您将声明参数为 LPSAFEARRAY * 并使用 SafeArray * 函数系列操纵数据。



请注意,您是负责任的要释放 BSTR ,你将要替换,如果你要替换它们。



你会得到所有有关数组大小和尺寸的信息,请参见 LPSAFEARRAY 和每个 BSTR 存储其字符串长度。






当您将 arr()作为string * some_length 声明时,时间 SAFEARRAY 将为 FADF_HAVEVARTYPE ,而 SafeArrayGetVartype 将返回 VT_ERROR 。安全数组的每个元素都将是一个预先分配的blob,它们是 some_length 宽字符( some_length * 2 字节),没有零终止符或字符串长度单独存储。可以说,这是更容易的工作,因为它是预先分配的,你可以简单地填充每个元素的现有记忆。






如果你使用纯粹的字符串,没有固定的长度,你也可以通过它们的方式与传递指针的方式相同:

 声明函数myFunc ...(byval strings as longptr,byval count as long)



  dim s()as string 
redim s(1到5)

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

然后C ++方面您将收到第一个字符串的 BSTR * ,并前进到您将添加的下一个字符串 1 就像你通常用指针数学一样。你需要传递元素的数量作为一个单独的参数来知道有多少个字符串。



这对于固定长度的字符串不起作用。


Just as the question says. I would like to be able to make an array of strings in some VBA code, in this code I would like to make them a certain length. Then how would I pass them into a C++ DLL, in the DLL I would like to store a string in each element and make these elements accessible from the VBA afterwords. I have already done this for a single string, and for a double array as follows.

Dim myStr As String * sizeConst

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

Then passing them to a DLL from within the VBA.

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

Then in the DLL I can step through each element in the double array. However I don't know how to do this for a string array. I am unsure about the actual memory size of the strings I would be passing in from the VBA would they be of size sizeConst + 1? I need to know this to know how much I should increment to get to the next string element. Can someone show me how to declare a string array in VBA with a constant length for each element. Then how to pass that array to the DLL and how to increment to the next element in the string array in the DLL.

解决方案

When you declare arr() as string in a Declared function, VB will send out an LPSAFEARRAY* (a double pointer, SAFEARRAY**) consisting of BSTRs (FADF_BSTR | FADF_HAVEVARTYPE). That is, the conversion to LPSTR will not be performed.

On the C++ side you would declare the parameter as LPSAFEARRAY* and use the SafeArray* family of functions to manipulate the data.

Note that you are responsible for freeing BSTRs you are going to replace, if you are going to replace them.

You will get all the information about the array size and dimensions from the LPSAFEARRAY, and each BSTR stores its string length.


Same happens when you declare arr() as string * some_length, but this time the SAFEARRAY will be of FADF_HAVEVARTYPE only, and SafeArrayGetVartype will return VT_ERROR. Each element of the safe array will be a preallocated blob of some_length wide chars (some_length * 2 bytes), with no zero terminator or string length stored separately. Arguably it's even easier to work with, because it's preallocated, you can simply fill the existing memory of each element.


If you were to use mere strings, without fixed length, you could also pass them in the same way you are passing the pointer to double:

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

Then on the C++ side you would receive BSTR* of the first string, and to advance to the next string you would add 1 to it like you would normally do with pointer math. You need to pass number of elements as a separate parameter to know how many strings there are.

This will not work for fixed-length strings.

这篇关于如何在VBA / Excel中创建一个字符串数组,并将其发送到C ++ DLL,以便可以通过DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆