В общем, непросто сделать то, что вы просите, потому что VB просто не понимает строки и массивы ASCIIZ в стиле C.
Если ваша DLL не ожидает VB SafeArray BSTR, у вас возникнут некоторые трудности с ее заполнением.
Было бы просто сделать так, чтобы VB передавал массив Long (C int) со ссылкой на первый элемент, и вы могли бы заполнить его указателями на отдельные строки. Сторона VB может скопировать их в строки VB. Но в таком случае, кто располагает строками C и когда?
Если вы создаете массив VB и заполняете его строками предварительно заданного размера, вам все равно придется иметь дело с SafeArray на стороне C, поскольку вы не можете передать один элемент массива VB по ссылке и ожидать найдите в памяти оставшиеся строки, смежные с ним.
Лучший, самый безопасный метод - создать в вашей DLL SafeArray из так называемого Ansi BSTR и объявить функцию в VB как возвращающую массив строк. Тогда вам не нужно два вызова, потому что границы массива расскажут всю историю.
===== edit =====
Когда VB передает строковый массив в объявленную функцию, он делает некоторое вуду за кулисами. Сначала он преобразует все строки из Unicode в ублюдочную форму, обычно известную как Ansi BSTR. Для C они выглядят и могут рассматриваться как ASCIIZ или LPSTR, за исключением того, что вы не можете создавать или удлинять их обычным способом C, вы можете только заполнить их. На стороне C переданный массив выглядит как ppSA (SAFEARRAY **). BSTR Ansi - это серия указателей, на которые ссылается член pData SafeArray.
Вы абсолютно не можете передать одну строку из массива (как char *) и ожидать, что остальные строки, смежные с ней, будут в памяти. Вы должны передать сам массив и управлять им, используя SafeArray API (или знание структуры SA).
Вот почему лучший вариант - делать все это прямо в DLL. Создайте массив, используя SafeArrayCreate, затем создайте BSTR Ansi, используя SysAllocStringByteLen, и поместите эти строки (которые являются BSTR, то есть 4-байтовым указателем) в слоты массива. По возвращении VB выполняет свое вуду и конвертирует строки в Unicode для вас.
В VB ваша функция будет объявлена как возвращающая String ().