Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 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. На мой взгляд единственное важное положение в подобной задаче - соответствие типов передаваемых данных. Буду признателен за любую помощью

Ответить

  Ответы Всего ответов: 15  

Номер ответа: 1
Автор ответа:
 shuffle



Администратор

ICQ: 201502381 

Вопросов: 15
Ответов: 737
 Профиль | | #1 Добавлено: 15.07.07 00:50
Привел бы что ли сигнатуру функции, которую вызываешь.

Ответить

Номер ответа: 2
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #2 Добавлено: 15.07.07 19:43
Топстартеру ботать что такое ActiveX DLL and native DLL, тогда он поймёт почему длл на с++ работают тем макаром что он вызывает из дотнета, а длл на вб6 - нет. Или ботать как работать с ActiveXDLL - тоже в поиск по "CoCreateInstance"

Ответить

Номер ответа: 3
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #3
Добавлено: 15.07.07 20:48
В Maple не ActiveX-библиотека, а самая обычная (к слову называть ее native не совсем верно)

Ответить

Номер ответа: 4
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #4 Добавлено: 15.07.07 23:11
Ну что касается Maple библиотеки - я её вообще-то и в глаза не видел. Но как мне показалось, топстартер делает на вб6 обвзяку этой библиоткеки и пытается про declare'ить её в .net ...

Ответить

Номер ответа: 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 есть, результат ошибочный!
Указатель нулевой.

Ответить

Номер ответа: 8
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #8 Добавлено: 16.07.07 01:54
Ну то что я говорил... автор не понимает что длл собранная на вб6 и на сях сильно отличаются, кординально... И пытается прикрутить дллку собранную на вб6, точно так же как дллку собранную на сях

Ответить

Номер ответа: 9
Автор ответа:
 SergeyM



Вопросов: 1
Ответов: 8
 Профиль | | #9 Добавлено: 16.07.07 02:02
Да из VC6 ЭТА ЖЕ DLL ВЫЗЫВАЕТСЯ и сделана она в С. ИМЕННО ЭТА - maplec.dll Никаких VB6 DLL нигде никогда Maple не предлагали. Это простой файл модуля maple.bas подключаемый к проекту, который помогает читать Сишную API DLL.

Ответить

Номер ответа: 10
Автор ответа:
 SergeyM



Вопросов: 1
Ответов: 8
 Профиль | | #10 Добавлено: 16.07.07 02:05
Точно так же как Дэня Эпплеман толкует и адаптирует функции WinAPI для VB6 юзеров!

Ответить

Номер ответа: 11
Автор ответа:
 SergeyM



Вопросов: 1
Ответов: 8
 Профиль | | #11 Добавлено: 16.07.07 02:16
To HACKER
It is really native C DLL!!!!

Ответить

Номер ответа: 12
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #12 Добавлено: 16.07.07 02:32
Я конечно не исключаю что понял вопрос не так как надо, но..

Интерфейс собран на С и никакого отношения не имеет к ActiveX. А потом адаптирован к VB6.0 путем дополнительных ухищрений - надстройки в виде файла maple.bas, который собственно содержит декларации DLL и немного крутит со строками и байтами.
В ЭТОМ И ЕСТЬ ЗАДАЧА - ПЕРЕПИСАТЬ НЕ ВЕСЬ ДАЖЕ ФАЙЛ, А ХОТЯ БЫ САМЫЕ ВАЖНЫЕ ФУНКЦИИ ПОД НЕТ.


Так что VB вызывает классическую DLL, собранную в С.


Если это действительно делается обвязка той мепл длл на вб6, которая потом подключается в дотнет - тогда я всётаки прав. Если вызывается сама маплдлл из дотнета - тогда я не прав, пардон.

Ответить

Номер ответа: 13
Автор ответа:
 SergeyM



Вопросов: 1
Ответов: 8
 Профиль | | #13 Добавлено: 16.07.07 02:56
Все нормально! Именно так:
==Если вызывается сама маплдлл из дотнета.==

Я не совсем признаться дружу с битами-байтами.
Все же единственная проблема здесь - адекватная трансляция данных.
Вот, например, подскажите пожалуйста, каков точный аналог VB6 конструкции в VB.NET
xexpr = StrConv(expr + Chr$(0), vbFromUnicode)

Есть сомнения, что где-то не хватает какого-то паршивого знака или наоборот мешает его присутствие при трансляции.

Ответить

Номер ответа: 14
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #14
Добавлено: 16.07.07 05:04
Попробуй написать этот кусок на C++.NET, там точно не возникает никаких проблем.

Ответить

Номер ответа: 15
Автор ответа:
 SergeyM



Вопросов: 1
Ответов: 8
 Профиль | | #15 Добавлено: 16.07.07 05:40
+++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++
СУПЕР!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=================================================
=================================================

Проблема решена!
Да здравствуют русские программисты!
Да здравствует компания Maplesoft с ее математическим движком!!!!

А то в документации Maple. Это не работает в VB.NET и прочее!


ИТАК, КОЛЛЕГИ! БУДЬТЕ ОСТОРОЖНЫ!
Классическая конструкция VB6.0
xexpr = StrConv(expr + Chr$(0), vbFromUnicode)
конвертирует строку в bytes of ANSII реализации.
Maple также работает с ANSII реализацией.
Поэтому просто была необходима дополнительная конвертация, реализуемая в VB.NET семейством
System.Text.UnicodeEncoding.=========

По прежнему восхищаюсь VB.NET(VB6). И Maple конечно тоже!!!

Вся мощь ядра Maple в Ваших руках господа.
Конечно, надо бы переписать весь этот интерфейс под NET - он же платформенно независимый.
Хороший полноценный интерфейс с классами (ох не люблю я эту терминологию, семейство как то по-домашнему звучит. А на классы у ресского человека аллергия).
Но это уже будет совсем другая история. Наверное этим и займусь как следкет.

Всем СПАСИБО!
=================================================



Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам