Страница: 1 |
|
Вопрос: Экспорт пользовательских DLL из VB.NET
|
Добавлено: 14.07.07 20:42
|
|
Автор вопроса: SergeyM
|
Привет коллеги!
Восхищен NET платформой,но разговор не об этом. Всем нам интересно наполнить функциональностью собственный интерфейс написанный на VB (6 или NET). Для этого служит возможность вызова внешних DLL, сторонних пользователей-производителей.
Вот конкретная вещь: из VB6.0 прекрасно вызывается и работает библиотека DLL Maple - математической среды.
Однако при вызове ее же из VB.NET возвращается 0.
Перепробованы различные варианты подключения - в VB.NET их великое множество (поражает!), менялись протоколы передачи данных. Были также приведены в соответствие типы передаваемых данных - здесь важно упомянуть о различии в типе long для VB6.0 и VB.NET. Теперь long тип VB6 должен быть заменен типом integer - (32). Однако по-прежнему получаю ноль. С чем может быть связана эта проблема. Интересно заметить, что приготовленная средствами VC6 пользовательская библиотека прекрасно вызывается из VB.NET. Я протестировал такую возможность путем вызова DLL, складывающей просто два числа. В высшей степени интересна причина возможной проблемы. Не может ли быть это связано с некоторыми принципиальными ограничениями, заложенными в DLL Maple. На мой взгляд единственное важное положение в подобной задаче - соответствие типов передаваемых данных. Буду признателен за любую помощью
Ответить
|
Номер ответа: 5 Автор ответа: SergeyM
Вопросов: 1 Ответов: 8
|
Профиль | | #5
|
Добавлено: 16.07.07 00:25
|
Интерфейс собран на С и никакого отношения не имеет к ActiveX. А потом адаптирован к VB6.0 путем дополнительных ухищрений - надстройки в виде файла maple.bas, который собственно содержит декларации DLL и немного крутит со строками и байтами.
В ЭТОМ И ЕСТЬ ЗАДАЧА - ПЕРЕПИСАТЬ НЕ ВЕСЬ ДАЖЕ ФАЙЛ, А ХОТЯ БЫ САМЫЕ ВАЖНЫЕ ФУНКЦИИ ПОД НЕТ.
Вся в целом, эта штука называется OpenMaple для тех у кого есть запросите справку в Maple. Так что VB вызывает классическую DLL, собранную в С.
Само ядро Maple удалось запустить! То есть получен указатель на ядро, который входит передаваемым параметром во все остальные функции, которые и проводят вычисления. Вот, например функция EvalMapleStatement, получив такой указатель и строку в виде чистейшего Maple кода (например, "sin(x);"должна возвращать указатель на результат. При появлении ошибки возвращается ноль. Я измучался, мне уже и Maple не нужен , но причину установить - дело чести.
Итак,поехали
=================================================
VB 6.0 maple.bas file
Короче собственность maplesoft
=================================================
Public cb As MapleCallBack
Public kv As Long
'callback vector supplied to StartMaple
Type MapleCallBack
lpTextCallBack As Long
lpErrorCallBack As Long
lpStatusCallBack As Long
lpReadLineCallBack As Long
lpRedirectCallBack As Long
lpStreamCallBack As Long
lpQueryInterrupt As Long
lpCallBackCallBack As Long
End Type
Declare Function xStartMaple Lib "maplec.dll" Alias "_StartMaple@24" _
  ByVal NumArgs As Integer, ByRef Arguments As Long, _
ByRef mcb As MapleCallBack, ByRef user_data As Byte, _
ByVal info As Long, ByRef error As Byte) As Long
Declare Function xEvalMapleStatement Lib "maplec.dll" Alias "_EvalMapleStatement@8" _
  ByVal MKernelVector As Long, ByRef expr As Byte) As Long
В загрузке формы старт имеет вид:
Private Sub Form_Load()
Dim i As Integer
Dim error As String
' Dim args(0 To 1) As String
Dim argv(1 To 2) As String
argv(1) = "-i" ' Все что угодно здесь кажется работает
argv(2) = "/home/myinit" ' И тут тоже
' Init callbacks
cb.lpTextCallBack = 0 'GetProc(AddressOf TextCallBack)
cb.lpErrorCallBack = 0 ' GetProc(AddressOf ErrorCallBack)
cb.lpStatusCallBack = 0
cb.lpReadLineCallBack = 0
cb.lpRedirectCallBack = 0
cb.lpQueryInterrupt = 0
cb.lpCallBackCallBack = 0
' Start Maple
kv = StartMaple(2, argv, cb, 0, error)
'Возможны варианты kv = StartMaple(2, argv, cb, 0, 0)
If kv = 0 Then
MsgBox " Error starting Maple: " + StrConv(error, vbUnicode), vbCritical, ""
Unload Me
End
End If
End Sub
'ErrorCallBack - для генерации сообщений об ошибках, возникающих в Maple - не принципиально.
Далее, считаем что-нибудь в виртуальном Maple-сеансе:
Private Sub Command1_Click()
Dim TestHandler As Long
TestHandler = EvalMapleStatement(kv, "f:=cos(x);"
' Все, если TestHandler не нулевой (ну вроде 34582134), значит в памяти сидит ответ на задачу. Как его достать, пока оставим - для этого другие функции используются.
Следующим сообщением бросаю NET потуги!
Ответить
|
Номер ответа: 6 Автор ответа: SergeyM
Вопросов: 1 Ответов: 8
|
Профиль | | #6
|
Добавлено: 16.07.07 00:34
|
Пардон, еще VB6
======================================
Добавочные - надстроечные функции VB6
======================================
Public Function StartMaple( _
ByVal NumArgs As Integer, _
ByRef Arguments() As String, _
ByRef mcb As MapleCallBack, _
ByRef user_data As Byte, _
ByRef ErrorMsg As String) As Long
Dim i As Long
Dim error_message(0 To 2048) As Byte
ReDim args(0 To NumArgs) As Long
Dim arg0() As Byte
Dim MKernelVector As Long
Dim allargs As String
ReDim argoffset(0 To NumArgs) As Integer
Dim conv_args() As Byte
' convert args to byte arrays
allargs = ""
argoffset(0) = 0
arg0 = StrConv("mserver" + Chr$(0), vbFromUnicode)
args(0) = VarPtr(arg0(0))
For i = 1 To NumArgs
allargs = allargs + Arguments(i) + Chr$(0)
argoffset(i) = Len(allargs)
Next i
conv_args = StrConv(allargs, vbFromUnicode)
For i = 1 To NumArgs
args(i) = VarPtr(conv_args(argoffset(i - 1)))
Next i
error_message(0) = 0
MKernelVector = xStartMaple(NumArgs + 1, args(0), cb, user_data, 0, error_message(0))
ErrorMsg = StrConv(error_message, vbUnicode)
StartMaple = MKernelVector
End Function
Public Function EvalMapleStatement(ByVal MKernelVector As Long, expr As String) As Long
Dim xexpr() As Byte
xexpr = StrConv(expr + Chr$(0), vbFromUnicode)
EvalMapleStatement = xEvalMapleStatement(MKernelVector, xexpr(0))
End Function
Ответить
|
Номер ответа: 7 Автор ответа: SergeyM
Вопросов: 1 Ответов: 8
|
Профиль | | #7
|
Добавлено: 16.07.07 01:00
|
===============================================
Все предыдущее можно найти в файле maple.bas в корневой папке maple. Детали интерфейса можно найти в С хедерах maplec.h и еще парочке там же.
===============================================
Реализация подключения в NET
Module Module1
Public cb As MapleCallBack
Public kv As Integer
Public MKernelVector As Integer
Declare Function xStartMaple Lib "maplec.dll" Alias "_StartMaple@24" _
  ByVal NumArgs As Integer, _
ByRef Arguments As Integer, _
ByRef mcb As MapleCallBack, _
ByRef user_data As Byte, _
ByVal info As Integer, _
ByRef UserError As Byte) As Integer
Declare Auto Function xEvalMapleStatement Lib "maplec.dll" Alias "_EvalMapleStatement@8" _
  ByVal MKernelVector As Integer, ByRef expr As Byte) As Integer
Public Function StartMaple( ByVal NumArgs As Integer, ByRef Arguments() As String, ByRef mcb As MapleCallBack, ByRef user_data As Byte, ByRef ErrorMsg As String) As Long
Dim i As Integer
Dim error_message(0 To 2048) As Byte
Dim args(0 To NumArgs) As Integer 'Long
Dim arg0() As Byte
Dim allargs As String
Dim argoffset(0 To NumArgs) As Integer
Dim conv_args() As Byte
'Dim cb As MapleCallBack
' convert args to byte arrays
allargs = ""
argoffset(0) = 0
arg0 = System.Text.UnicodeEncoding.Unicode.GetBytes( _
"mserver" + Chr(0))
'args(0) = VarPtr(arg0(0))
Dim handle As GCHandle = GCHandle.Alloc(arg0(0), GCHandleType.Pinned)
Dim address As Integer = handle.AddrOfPinnedObject.ToInt32
args(0) = address
'handle.Free()
For i = 0 To NumArgs - 1
allargs = allargs + Arguments(i) + Chr(0)
argoffset(i) = Len(allargs)
Next i
conv_args = System.Text.UnicodeEncoding.Unicode.GetBytes(allargs)
For i = 1 To NumArgs
Dim handle_01 As GCHandle = GCHandle.Alloc(conv_args(argoffset(i - 1)), GCHandleType.Pinned)
Dim address_01 As Integer = handle_01.AddrOfPinnedObject.ToInt32
args(i) = address_01
Next i
error_message(0) = 0
MKernelVector = xStartMaple(NumArgs + 1, args(0), cb, user_data, 0, error_message(0))
ErrorMsg = System.Text.UnicodeEncoding.Unicode.GetString(error_message)
StartMaple = MKernelVector
End Function
' В форме ==========================
Public Sub Button1_Click( ByVal sender As System. Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim argv(0 To 2) As String
argv(1) = "-i"
argv(2) = "/home/myinit"
' Init callbacks
cb.lpTextCallBack = 0 'msd.DynamicInvoke(2, MAPLE_TEXT_OUTPUT, 4) 'GetProc(AddressOf TextCallBack)
cb.lpErrorCallBack = 0 ' AddressOf ErrorCallBack
cb.lpStatusCallBack = 0
cb.lpReadLineCallBack = 0
cb.lpRedirectCallBack = 0
cb.lpQueryInterrupt = 0
cb.lpCallBackCallBack = 0
' Start Maple
kv = StartMaple(2, argv, cb, 0, 0)
End Sub
Private Sub Button2_Click( ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim HeandlerMapleCalc As Integer
HeandlerMapleCalc = EvalMapleStatement(kv, "sin(x);"
TextBox2.Text = HeandlerMapleCalc
End Sub
Вход в DLL есть, результат ошибочный!
Указатель нулевой.
Ответить
|
Страница: 1 |
Поиск по форуму