VB.NET: Passing Pointer to structure to the DLL function ?

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

VB.NET: Passing Pointer to structure to the DLL function ?

Сообщение radislav » 01.04.2008 (Вт) 2:42

Hello Forum,

A simple question for people who knows :

I have DLL written in C.NET with the following function API declaration :

long DLLFunc(void * ptr1, wchar_t * str1, structType * structName)

The DLL function must update/change the contents
of the structure and return it to the application.
-------------------------------------------------------------------------------
VB.NET declaration :

Public Structure MySubType
Public ChArray() As Char
Public p1 As UInteger
Public p2 As UInteger
Public p3 As UInteger
Public p4 As UInteger
Public p5 As UInteger
Public p6 As UInteger
End Structure

Public Structure MyType
Public EntryDesc As MySubType
Public v1() As Byte
Public Err As UShort
End Structure

Public Entry1 as new MyType()
Redim Entry1.EntryDesc.ChArray(107)
Redim Entry1.v1(7)

Private Declare Unicode DLLFunc Lib "DLLName.dll" ( _
ByVal hInstance As Integer, _
ByVal lpKeyFullName As String, _
ByRef lpDescriptor As MyType) As Long

All i am trying with calling sequence, not helps !!!!!

Err = DLLFunc(Handle, "test", Я идиот! Убейте меня, кто-нибудь!????(must be pointer to Entry1))

How i can pass pointer of the Entry1 to the DLL ?

I spent more than 3 days in searching all possible sources (books, forums, MSDN, codeguru .. ++)
S-O-S !
Please, help.
----> The best things are ahead ---->>

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 01.04.2008 (Вт) 8:11

Код: Выделить всё
Imports System.Runtime.InteropServices

Public Class Form1
  Declare Unicode Function DLLFunc Lib "DLLName.dll" ( _
   ByVal hInstance As Integer, _
   ByVal lpKeyFullName As String, _
   ByVal lpDescriptor As MySubType) As Long ' As Integer???


  <StructLayout(LayoutKind.Sequential)> _
  Public Class MySubType
    Public ChArray() As Char
    Public p1 As UInteger
    Public p2 As UInteger
    Public p3 As UInteger
    Public p4 As UInteger
    Public p5 As UInteger
    Public p6 As UInteger
  End Class

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim Err As Long
    Dim Entry1 As New MySubType
    ReDim Entry1.ChArray(10)

    Err = DLLFunc(Handle, "test", Entry1)
  End Sub

End Class


??? :roll:
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 01.04.2008 (Вт) 8:18

Еще бы увидеть прототип структуры structType, было бы совсем хорошо.
Весь мир матрица, а мы в нем потоки байтов!

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 01.04.2008 (Вт) 8:27

А еще лучше проект этой dll
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

Сообщение radislav » 01.04.2008 (Вт) 9:33

Good morning,

Thank you for answers, but i am still got the same error window :

Nord777, your definitions are exactly tryed.

The VB.NET stops at the calling line with green highlite and .....
----------------------------------------------------------------------------
! SafeArrayTypeMismatchException was unhandled
----------------------------------------------------------------------------

Specified array was not of the expected size.

"Ta-ta-ta......
bal-bla-bla " ...... helpless help with roots in MSDN and so on
---------------------------------------------------------------------------

I have read about marshalling also, maybe one (from 100's) of the "Marshals" can help ?
I don't believe, that Miscrosoft not invent some method for VB.NET
to get a simple pointer to the ANY data block or
object (like in my case) in memory !
I remember, In VB6 was type Any. What happens to him ?
----> The best things are ahead ---->>

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 01.04.2008 (Вт) 12:05

Must be:
Код: Выделить всё
<StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Unicode)> Structure MySubType
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=108)> ChArray() As Char
Public p1 As UInteger
Public p2 As UInteger
Public p3 As UInteger
Public p4 As UInteger
Public p5 As UInteger
Public p6 As UInteger
End Structure

Private Declare Unicode DLLFunc Lib "DLLName.dll" ( _
ByVal hInstance As Integer, _
ByVal lpKeyFullName As String, _
ByVal lpDescriptor As MyType) As Integer


Read this (Russian): http://www.vbstreets.ru/VBdotNET/Articles/66311.aspx
Весь мир матрица, а мы в нем потоки байтов!

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

Tnx Viper and Nord777, but still have a LITTLE problem ....

Сообщение radislav » 01.04.2008 (Вт) 19:37

Here is the real printouts from SDK documentation :

C Types Declaration :

typedef struct {
wchar_t Name_AWC[44];
unsigned long Size_UL;
unsigned long Address_UL;
unsigned long Depth_UL;
unsigned long Multiplicity_UL;
unsigned long Bitmask_UL;
} GDB_ENTRY_DESCRIPTOR_DT;

typedef struct
{
GDB_ENTRY_DESCRIPTOR_DT Descriptor_ST;
unsigned char Value_AUC[8];
unsigned short Error_US;
} GDB_GET_SET_ENTRY_DT;

C# DLL API Declaration :

int GdbHimDevEntryGetDescriptor(
void* GdbDevHandle_PST,
const wchar_t* KeyFullName_PWC,
GDB_ENTRY_DESCRIPTOR_DT* Descriptor_PST)


The DLL changes the values of Descriptor_PST and return they to me for further processing.


Declaration and usage in VB :


<StructLayout(LayoutKind.Sequential, Pack:=1, harSet:=CharSet.Unicode)> Public Class GDB_ENTRY_DESC_DT
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=43)> Public a_Name_AWC() As Char
Public b_Size_UL As UInteger
Public c_Address_UL As UInteger
Public d_Depth_UL As UInteger
Public e_Multiplicity_UL As UInteger
Public f_Bitmask_UL As UInteger
End Class

Public Class GDB

Private Declare Unicode Function GdbHimDevEntryGetDescriptor Lib "GdbHimServices.dll" ( _
ByVal hInstance As Integer, _
ByVal lpKeyFullName As String, _
ByVal lpDescriptor As GDB_ENTRY_DESC_DT) As Integer

Public Desc0 As New GDB_ENTRY_DESC_DT()


Public Shared Function dgb_GetDescriptorANDValue(ByVal ParName As String) As Long
Dim DevErr As Integer
Dim Desc0 As New GDB_ENTRY_DESC_DT()
ReDim Desc0.a_Name_AWC(43)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
DevErr = GdbHimDevEntryGetDescriptor(Ptr2Dev, ParName, Desc0)
......
......
.....

End Function

End Class


Results : It Passes interpretation and runs OK

BUT ! The DLL can't change the data inside the structure. I get it back with Nothing and zero values.
(It must return the name of the parameter and its address and other parameters filled with values from the data tables in DLL)
--------------------------------------------------------------------------
!!!! When using Byte Array (and ByRef declaration) the DLL can change the values in the Array and get it back filled with correct data.
---------------------------------------------------------------------------

What you suggest ?
----> The best things are ahead ---->>

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 02.04.2008 (Ср) 8:49

Код: Выделить всё
  Private Declare Unicode Function GdbHimDevEntryGetDescriptor Lib "GdbHimServices.dll" ( _
    ByVal hInstance As Integer, _
    ByVal lpKeyFullName As String, _
    <[In](), Out()> ByVal lpDescriptor As GDB_ENTRY_DESC_DT) As Integer

?
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

It works !!

Сообщение radislav » 02.04.2008 (Ср) 13:07

Nord777,

Thank you for this solution ! It works wonderfull !!!

Also, Thank to Viper and all people, who helping me on this forum !

Sorry for delay, I was so tired yesterday (after 3 nights + days) trying to solve this. So I ZASNUL near the computer till morning.

Now, i am continuing to pass the descriptor to the next DLL function in order to get the value of the inside parameter ...........

Let see what be happens from now.

Best regards,
Radislav.
----> The best things are ahead ---->>

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

Debugger exiting takes more than 5 min.

Сообщение radislav » 02.04.2008 (Ср) 20:33

HELP - HELP - HELP

Something happens,

Debugger can't exit after "stop debugging" more than 5 minutes every time i need to stop debugging session !
What to do ?
----> The best things are ahead ---->>

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 03.04.2008 (Чт) 9:00

Explain a problem in more detail
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

First I would like to put here the final WORKING solution

Сообщение radislav » 03.04.2008 (Чт) 21:30

FOR ALL VB.NET USERS, WHO ARE DEALING WITH SUCH KIND OF PROBLEM
------------------------------------------------------------------------------------------

// C Types Declaration :

typedef struct {
wchar_t Name_AWC[44];
unsigned long Size_UL;
unsigned long Address_UL;
unsigned long Depth_UL;
unsigned long Multiplicity_UL;
unsigned long Bitmask_UL;
} GDB_ENTRY_DESCRIPTOR_DT;

typedef struct
{
GDB_ENTRY_DESCRIPTOR_DT Descriptor_ST;
unsigned char Value_AUC[8];
unsigned short Error_US;
} GDB_GET_SET_ENTRY_DT;

C# DLL API Declaration :

// --- First API function ----

int GdbHimDevEntryGetDescriptor(
void* GdbDevHandle_PST,
const wchar_t* KeyFullName_PWC,
GDB_ENTRY_DESCRIPTOR_DT* Descriptor_PST)

// --- Second API function ----

Int GdbHimDevEntryGetValue(
void * GdbDevHandle_PST,
GDB_GET_SET_ENTRY_DT* Entries_PST,
unsigned long EntriesCount_UL)

// "EntriesCount_UL" used in order to get more than single value sending an array of descriptors.

----------------------- VB.NET ----------------------------------------

'' I defined a single public class that contains the "GDB_GET_SET_ENTRY_DT" structure


<StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Unicode)> Public Class GDB_ENTRY_DESC_DT_1
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=44)> Public a_Name_AWC() As Char
<MarshalAs(UnmanagedType.U4, SizeConst:=4)> Public b_Size_UL As UInteger
<MarshalAs(UnmanagedType.U4, SizeConst:=4)> Public c_Address_UL As UInteger
<MarshalAs(UnmanagedType.U4, SizeConst:=4)> Public d_Depth_UL As UInteger
<MarshalAs(UnmanagedType.U4, SizeConst:=4)> Public e_Multiplicity_UL As UInteger
<MarshalAs(UnmanagedType.U4, SizeConst:=4)> Public f_Bitmask_UL As UInteger
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8 )> Public g_Value_AUC() As Byte
<MarshalAs(UnmanagedType.U2, SizeConst:=2)> Public h_Error_US As UShort
End Class


'' Calling function :

Public Shared Function dgb_GetDescriptorANDValue(ByVal ParName As String) As UInteger
Dim DevErr As UInteger
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim Desc1 As New GDB_ENTRY_DESC_DT_1()
ReDim Desc1.a_Name_AWC(43)
ReDim Desc1.g_Value_AUC(7)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Get Descriptor
DevErr = GdbHimDevEntryGetDescriptor(Ptr2Dev, ParName, Desc1)
'' Get Value
DevErr = GdbHimDevEntryGetValue(Ptr2Dev, Desc1, 1)
''
'' Handling Value (from Desc1.g_Value_AUC(7))
''
Return (DevErr)
End Function


'' Each time, I need a single value I call this function and get the Value.

IT WORKS WONDERFULL ! (Thanks to your help)

Question : Can I define an array of Get/Set descriptors in order to get more than a single value ?
----> The best things are ahead ---->>

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

!! Debugger Problem !!

Сообщение radislav » 03.04.2008 (Чт) 21:46

Each time when debugger encounters and Exception of any king or other error, i am clicking on Stop Debugger button.

Than :

1. Nothing happens (about 30 sec) and all activities freezes ......

2. After 30 sec. - Message window appears (from debugger), Notifying that the Stope Debugging in progress (See attached file),
and i am suggested to let him finish.
Or I can Push STOP button to stop immediately. But in this case,
I have a big problem - The process, running my program,
stays in Task Tray, and i am can't run a new debugger session.
Any attempt to remove this process - without any results.
So, I need to reboot the PC (or Logoff/Logon user).

3. If i am waiting, its takes about 5 minutes to finish all debugger open processes.
It finishes, and i can continue to work. But this very hard way to debug
the application.

What is the problem ?
What to do ?

Thank you in advance,

Radik.
Вложения
Deb-Stucking.JPG
A message box from Debugger.
Deb-Stucking.JPG (17.23 Кб) Просмотров: 4624
----> The best things are ahead ---->>

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 04.04.2008 (Пт) 9:47

Question : Can I define an array of Get/Set descriptors in order to get more than a single value ?
Function "GdbHimDevEntryGetValue" allows it?
You have not given the full description of parameters.
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

Сообщение radislav » 04.04.2008 (Пт) 12:34

Yes, the C function allows it.
You can declare Array of descriptors, fill then with the first calling to Get Descriptor (one by one) and than to call GetValue function with all list and get values for all needed parameters in a single call.
For this reason they put "EntriesCount_UL" parameter in call

Can i, in VB.NET, to define Array of these structures in order to it to DLL ?
----> The best things are ahead ---->>

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 05.04.2008 (Сб) 7:53

Код: Выделить всё
<StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Unicode)> _
  Public Class GDB_ENTRY_DESC_DT_1
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=44)> Public a_Name_AWC() As Char
    Public b_Size_UL As UInteger
    Public c_Address_UL As UInteger
    Public d_Depth_UL As UInteger
    Public e_Multiplicity_UL As UInteger
    Public f_Bitmask_UL As UInteger
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Public g_Value_AUC() As Byte
    Public h_Error_US As UShort

    Sub New()
      ReDim a_Name_AWC(43)
      ReDim g_Value_AUC(7)
    End Sub
  End Class




  Public Shared Function dgb_GetDescriptorANDValue(ByVal ParName As String) As UInteger
    Dim Ptr2Dev As Integer = 0 'Unknown to me value, therefore a zero
    Dim DevErr As UInteger
    Dim Desc1(9) As GDB_ENTRY_DESC_DT_1

    For i As Integer = 0 To Desc1.Length - 1
      Desc1(i) = New GDB_ENTRY_DESC_DT_1
      ' Get Descriptor
      DevErr = GdbHimDevEntryGetDescriptor(Ptr2Dev, ParName, Desc1(i))
      'If DevErr <> 0 Then Return DevErr
    Next

    ' Get Values
    DevErr = GdbHimDevEntryGetValue(Ptr2Dev, Desc1(0), Desc1.Length)

    Return (DevErr)
  End Function


So?
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

Сообщение radislav » 05.04.2008 (Сб) 11:30

Thank you,
I will try this today.
----> The best things are ahead ---->>

radislav
Начинающий
Начинающий
 
Сообщения: 22
Зарегистрирован: 26.01.2003 (Вс) 23:46
Откуда: Israel

Сообщение radislav » 06.04.2008 (Вс) 9:40

The customer takes the hardware equipment to perform some tests in his lab for a few days. I will continue check this subject after.
Mean wale, i must wait.
I will be back.

Question :
How can i open a new project and to add an existing form from early project.
Just adding the design and vb files of the form to the new project not helps.
----> The best things are ahead ---->>

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 06.04.2008 (Вс) 11:54

How can i open a new project and to add an existing form from early project.
Just adding the design and vb files of the form to the new project not helps.

1) In Solution Explorer click on icon "Show All Files"
2) Right click on a file which should be included in the project. Select menuItem "Include in Project"
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

    TopList