2015-04-29 3 views
0

У меня возникла проблема повторно использовать C++ DLL, используемую с VB 6.0 на VB.NET.Вызов неуправляемого кода C++ dll из VB.NET

Мой помощник запрограммировал код в VB6.0, который вызвал в Ansi C++ DLL, запрограммированную в VC 6.0 ++.

Функция объявляется следующим образом;

CTYPE DWORD CCONV IniciaGestion(HWND newhventana, char *ficheroini, char *mensaerror) 

Бывший код в VB6.0 назвал эту DLL таким способом

status = IniciaGestion(Me.hWnd, "DRVCOMM2.ini", mensaerror) 

где mensaerror является выходным параметром определяется как

Public mensaerror As String * 256 

Теперь я могу использовать эту DLL из VB .СЕТЬ?

У меня проблема с объявлением этого третьего параметра.
Я использую это заявление

<DllImport("GestionPrg.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Ansi)> _ 
Public Shared Function IniciaGestion(<MarshalAs(UnmanagedType.I4)> ByVal a As Integer, <MarshalAs(UnmanagedType.LPStr)> ByVal b As String, <OutAttribute(), MarshalAs(UnmanagedType.LPTStr)> ByRef c As String) As Long 

и функция вызывается следующим

Dim mensaerror As String 

Class1.IniciaGestion(Me.Handle, "C:\\Windows\\DRVCOMM2.ini", mensaerror) 

Я отладки и функция вызывается, но когда я иду к установленному значению для mensaerror в коде C++ создается исключение.

Может ли кто-нибудь помочь мне в объявлении в VB.NET?

ответ

0

Пожалуйста, используйте 4 пробельные перед вашим кодом - делает его намного легче читать ...

<System.Runtime.InteropServices.DllImport("YourDLL.dll")> _ 
Public Shared Function IniciaGestion(ByVal a As IntPtr, ByRef b As String, ByRef c As String) As Long 
End Function 

Private Sub CallCode() 
    Dim mensaerror As String = "" 
    IniciaGestion(Me.Handle, "C:\Windows\DRVCOMM2.ini", mensaerror) 
End Sub 

Если сделать работу ...

+0

, если вы на самом деле что вы делаете, вы никогда не объявляете строки 'ByRef' при вызове во внешнюю библиотеку в VB. – GSerg

-1
Public Declare Ansi Function IniciaGestion Lib "GestionPrg.dll" (ByVal a As IntPtr, ByVal b As String, ByVal c As String) As Integer 

И не забудьте выделить место для c перед вызовом, например делая

Dim mensaerror As String = Space(256) 

Чем больше .NET способ сделать это, чтобы использовать StringBuilder хотя:

Public Declare Ansi Function IniciaGestion Lib "GestionPrg.dll" (ByVal a As IntPtr, ByVal b As String, ByVal c As StringBuilder) As Integer 

, для которых вы установите требуемую емкость перед вызовом:

Dim mensaerror = New StringBuilder(256) 
+0

«more .NET way» - это * not * use 'Declare' - использовать атрибут DllImport. «Объявить» только в VB для обратной совместимости с VB6. –

+0

Вы пропустили главное, но да, это, возможно, будет еще больше .NET. Сказав это, 'Declare', конечно, не только для обратной совместимости, потому что они добавили функцию Ansi/Unicode/Auto, которая отсутствовала в исходном VB, и они [не упоминают] (https://msdn.microsoft.com/en-us/library/4zey12w5.aspx), это не рекомендуется или устарело, как это делается для [фактических вещей с обратной совместимостью] (https://msdn.microsoft.com/en- нас/библиотека/Microsoft.VisualBasic.Compatibility.VB6 (v = vs.110) .aspx). – GSerg

+0

Ссылка, которую вы дали («фактическая обратная совместимость ...»), касается пространства имен VB6. «Declare» - это синтаксис VB6, а не проблема с пространством имен VB6. –

Смежные вопросы