Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Массив из ДЛЛ / 10 сообщений из 10, страница 1 из 1
31.01.2012, 14:45
    #37640081
Абкт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Добрый день, уважаемые!!!
Есть ДЛЛ, написанная на Delphi. В ней есть процедура, которая возвращает указатель на массив.
В Delphi ее вызвать просто
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
//...
const
dll = 'share.dll';

type
  TArr = array of Integer;
  TPArr = ^TArr;
//...
  procedure MInit(aPArr : TPArr); stdcall; external dll name 'MInit';

//...

procedure TForm2.BitBtn3Click(Sender: TObject);
var
  Arr : TArr;
  PArr : TPArr;
  i: Integer;
begin
  PArr := Addr(Arr);
  MInit(PArr);
  Memo1.Lines.Clear;
  for i := 0 to length(Arr)-1 do Memo1.Lines.Add(IntToStr(Arr[i]));
//...
end;
//...



Хотелось бы вызывать ее в VBA.
В гугле искал, ничего внятного не нашел.
Может быть, все просто, но я в VBA не силен.
...
Рейтинг: 0 / 0
31.01.2012, 15:10
    #37640138
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Ничего не просто. Во-первых, VB не очень-то дружит с указателями, во-вторых, совсем не знаком с дельфевыми массивами. Если будет указатель хотя бы на SAFEARRAY, то с этим уже можно как-то работать. В противном случае для vb это указатель на байтовый массив неизвестной величины. Если вы знаете, что представляют из себя дельфевые массивы в памяти в "сыром" виде, если они хранят и свой размер как SAFEARRAY, можете попытаться раскодировать эти байты.
...
Рейтинг: 0 / 0
31.01.2012, 15:29
    #37640176
Абкт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
авторНичего не просто. Во-первых, VB не очень-то дружит с указателями, во-вторых, совсем не знаком с дельфевыми массивами. Если будет указатель хотя бы на SAFEARRAY, то с этим уже можно как-то работать. В противном случае для vb это указатель на байтовый массив неизвестной величины. Если вы знаете, что представляют из себя дельфевые массивы в памяти в "сыром" виде, если они хранят и свой размер как SAFEARRAY, можете попытаться раскодировать эти байты.
Хорошо, а если размер массива и тип данных известен? В данном случае - Long.
...
Рейтинг: 0 / 0
31.01.2012, 16:15
    #37640275
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Можно попробовать так:
Dim arr(0 to размер_массива) as Long
CopyMemory arr(0), указатель, размер_массива * 4
...
Рейтинг: 0 / 0
31.01.2012, 16:29
    #37640307
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Можно SAFEARRAY и на стороне VB/VBA заполнить.
...
Рейтинг: 0 / 0
31.01.2012, 16:47
    #37640348
Абкт
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Public Declare Sub MInit Lib "share.dll" (ByRef aParr As Variant)


Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Sub Макрос1()
    '
    ' Макрос1 Макрос
    '
    'On Error Resume Next
    Dim res(0 To 2) As Long

    CopyMemory res(0), aParr, 3 * 4
    Range("A1").Value = res(0)
    Range("A2").Value = res(1)
    Range("A3").Value = res(2)
End Sub


Нули выдает, а должны быть значения.
...
Рейтинг: 0 / 0
31.01.2012, 16:54
    #37640362
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Абкт,

как-то совсем плохо выглядит.

1) Option Explicit
2) Описать в Declare aParr As Long
3) Описать в процедуре переменную, которая будет принимать адрес первого элемента массива.
4) Вызвать-таки MInit.
...
Рейтинг: 0 / 0
31.01.2012, 16:58
    #37640371
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Даже ещё хуже. MInit не возвращает (адрес начального элемента массива), а принимает по значению адрес array of Integer.

Каша, короче.
...
Рейтинг: 0 / 0
31.01.2012, 17:45
    #37640458
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Если дельфевый Integer = вбшный Integer, то * 2. Я почему-то подумал, что Long.
...
Рейтинг: 0 / 0
31.01.2012, 18:11
    #37640502
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив из ДЛЛ
Antonariy,

это, кажется, в первых версиях Дельфи Integer был generic-ом, и мог выбираться 16/32, сейчас вроде 32-битный (если снова не generic 32/64).

Абкт,
короче, пробуй так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Option Explicit

Public Declare Sub MInit Lib "share.dll" (ByRef aParr As Long)

Sub Макрос1()
    Dim res(0 To 2) As Long

    MInit res(0)

    Range("A1").Value = res(0)
    Range("A2").Value = res(1)
    Range("A3").Value = res(2)
End Sub

Но MInit должна корректно работать с массивом, не выходя за его границы. Если она это делает, ориентируясь на High(), то вряд ли что-то хорошее выйдет.
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Массив из ДЛЛ / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]