lundi 20 juin 2016

Call unmanaged C++ DLL from VB.NET

I'm new to C++ and have attempted to build a dll for use in a VB.NET (VS2013) project. I am essentially just wanting access to the partial sort function available in C++

I have created a simple form in a test vb project. I have compiled the dll in VC++(2013) and copied it to the directory specified in the VB code.

I click the button on the form and then get the error message:

An unhandled exception of type 'System.AccessViolationException' occurred in System.Windows.Forms.dll

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

I suspect (as I don't really know what I'm doing with pointers) that the vb code is almost certainly incorrect.

Any help appreciated.

C++ Code:

CPartialSort.h

extern "C" __declspec(dllexport) double* PSort(double* vArr, int Arrlength, int SortLength); 

CPartialSort.cpp

#include "stdafx.h"
#include "CPartialSort.h"
#include <array>
#include <vector>

double* PSort(double* vArr, int Arrlength, int SortLength)
{
    int i;
    std::vector<double> myvector(vArr, vArr + Arrlength);

    // using default comparison (operator <):
    std::partial_sort(myvector.begin(), myvector.begin() + SortLength, myvector.end());

    //reuse vArr
    for (i = 0; i < Arrlength; i++)
    {
        vArr[i] = myvector[i];
    }
    return vArr;
}

VB.NET Code:

Imports System.Runtime.InteropServices

Dll Function

<DllImport("CPartialSort.dll", CallingConvention:=CallingConvention.Cdecl)> _
 Public Shared Function PSort(ByRef vArr() As Double, _ 
                             ArrayLength As Integer, SortLength As Integer) As Double
 End Function

A button on a form runs the following code.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim dllDirectory As String = "C:Usersuser1DocumentsVisual Studio 2013ProjectsWindowsApplication1"
    Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + dllDirectory)

    Dim testarray(10) As Double
    For i = 0 To 9
        testarray(i) = 10 - i
    Next
    Dim thepointer As IntPtr = PSort(testarray, testarray.Length, 5)
    Dim thedouble As Double() = New Double(0) {}
    Marshal.Copy(thepointer, thedouble, 0, testarray.Length)
    MsgBox(thedouble(0))

End Sub

Aucun commentaire:

Enregistrer un commentaire