Необработанная ошибка AccessViolationException Ошибка вызова библиотеки DLL в VB.Net - PullRequest
0 голосов
/ 06 октября 2011

Я пытаюсь вызвать C ++ - скомпилированную DLL из VB.net, и у меня возникают некоторые проблемы. Кажется, что есть очевидное решение, но я не могу понять это.

Вот объявление функции в C ++:

 MyFunction(int trailingaveragesize, double sigmasize, int myflag, int sizeSeries, double *Xdata, double *Ydata, int sizeinputparameter, int *averagePairs, double *PositionsSize, double *PnLSize)

Вот как я это называю в VB.Net:

 Call MyFunction(200, 1, 1, 230, a_PriceSeries(0), a_PriceSeries(0), 1, a_Averages(0), a_PositionSeries(0), a_PnLs(0))

Максимальный размер входных матриц определяется sizeSeries (230), а размер всех моих входных матриц - 10000 (только чтобы случайно не переполниться), но все же я получаю необработанную ошибку AccessViolationException

 Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Мой вопрос: если я не превышаю границы своих матриц, по каким другим причинам возникнет эта ошибка? Это потому, что я передаю только первую запись в моей матрице ByReference, а затем пытаюсь получить доступ к другим элементам этой матрицы? Если это так, как бы я это исправить?

EDIT:

Вот как я это объявляю в VB

 Declare Function MyFunction Lib "C:\Dev\asdf.dll" (ByVal trailingaveragesize As Long, ByVal sigmasize As Double, ByVal myflag As Long, ByVal sizeSeries As Long, ByRef Xdata As Double, ByRef Ydata As Double, ByVal sizeinputparameter As Long, ByRef averagePairs As Long, ByRef PositionsSize As Double, ByRef PnLSize As Double) As Double

Ответы [ 3 ]

1 голос
/ 06 октября 2011

p-invoke - это вызов платформы и способ вызова нативных API с помощью .NET.Ваше объявление в настоящее время не настроено для передачи массивов, и это не должно быть сделано ByRef.

Попробуйте изменить ByRef на ByVal для переменных массива и объявите их с помощью () для обозначения массива.

1 голос
/ 06 октября 2011
Declare Function MyFunction Lib "C:\Dev\asdf.dll" (ByVal trailingaveragesize As Long, _
  ByVal sigmasize As Double, ByVal myflag As Long, ByVal sizeSeries As Long, 
  ByRef Xdata As Double, ByRef Ydata As Double, ByVal sizeinputparameter As Long, 
  ByRef averagePairs As Long, ByRef PositionsSize As Double, ByRef PnLSize As Double) As Double

Объявление просто неверно, это похоже на объявление vb6. int в C-коде - это Integer в vb.net, а не Long. Xdata и Ydata, скорее всего, будут массивами, а не двойными. Объявите их как ByVal Double (). Другие аргументы byref труднее угадать.

0 голосов
/ 14 февраля 2014

Ошибка в том, что когда я объявлял переменную типа long, она должна иметь тип integer.Переменная rc была ошибочно объявлена:

Здесь код моей формы Form1 (он имеет одну кнопку и один текстовый блок):

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub

Здесь код для Button.Click (он инициализирует некоторые переменные, используемые для вызова функции в DLL):

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim arg1 As String
    Dim arg2 As String
    Dim ret As String

Вот переменная rc, которую я объявил как long.Это должно быть целое число

    Dim rc As long
        ret = "123456789012345678901234567890123"
        arg1 = "123456"
        arg2 = "1234567890123456"
        rc = myFunction(arg1, arg2, ret)
        If (rc = 0) Then
            TextBox1.Text = ret
        Else
            TextBox1.Text = "Result not OK"
        End If
    End Sub
End Class

myFunction было объявлено как целое число в myDll:

extern __declspec(dllexport) int __stdcall myFunction(unsigned char * pszArg1, unsigned char * pszArg2, char * pszReturn)

Вот как я объявил MyFunction в моем Visual Basic Express 2010:

Module Module1

    Public Declare Function myFunction Lib "C:\Users\me\MyProjects\myDll\bin\Debug\myDll.dll" (ByVal Arg1 As String, ByVal Arg2 As String, ByVal ret As String) As Integer

End Module
...