1
votes

Windows 10 and Visual Studio 2017.

To reference the DLL in the VB.NET project: I DID vb.net project properties > Add > Reference > Browse > my DLL in project directory of this vb.net project > Add > checkmark DLL > OK

...and I get this error: "A reference [.dll] could not be added."

Here is Visual-C++ 2017pro DLL project properties ... enter image description here

Here is function in DLL called by VB.NET (after addition of extern "C" & __stdcall):

 extern "C" BASICDLL_API  int __stdcall Connect()
{
    char manufacturer[] = "Acme Inc.  ";
    char product[] = "System          ";
    return BDLL_Connect(manufacturer, product);
}

Here are VB.NET declarations for Fns. within DLL....

Imports System.Runtime.InteropServices

Module main_board_interface

    Public Class NativeMethods
        <DllImport("myDLL.dll")>
        Public Shared Function Connect() As Integer
        End Function

        <DllImport("myDLL.dll")>
        Public Shared Function Read_Parameters(ByVal board As Byte, ByRef params As UInt16()) As Integer
        End Function

        <DllImport("myDLL.dll")>
        Public Shared Function Write_Parameter(ByVal board As Byte, ByRef param_ID As Byte, value As Int32) As Integer
        End Function

        <DllImport("myDLL.dll")>
        Public Shared Function Save_Parameter(ByVal board As Byte, ByRef param_ID As Byte) As Integer
        End Function

        <DllImport("myDLL.dll")>
        Public Shared Function Disconnect() As Integer
        End Function
    End Class

End Module

..........................................

After adding the DLL and running the program, I got below error when I clicked the command button that called the Connect() method in the DLL:

Private Sub Button_test_main_board_Click(sender As Object, e As EventArgs) Handles Button_test_main_board.Click
    Dim return_status = main_board_interface.NativeMethods.Connect()  <<<<<<<<<<<<<<  BELOW ERROR HERE.
    If return_status = 0 Then
        TextBox_main_board_comm.Text = "Connection with Main Board V1" & vbCrLf
    Else
        TextBox_main_board_comm.Text = "No connection with Main Board V1" & vbCrLf
        Return
    End If

enter image description here

ERROR DETAILS...

System.BadImageFormatException occurred
  HResult=0x8007000B
  Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
  Source=v1
  StackTrace:
   at NationalInstruments.Examples.ContAcqVoltageSamples_IntClk.main_board_interface.NativeMethods.Connect()
   at NationalInstruments.Examples.ContAcqVoltageSamples_IntClk.MainForm.Button_test_main_board_Click(Object sender, EventArgs e) in C:\PRIMARY\...\WORK\SYSTEM GUI V1\MainForm.vb:line 1579
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at NationalInstruments.Examples.ContAcqVoltageSamples_IntClk.MainForm.Main()

I still get this error after addition of extern "C" and __stdcall 'decorations' to DLL connect() function.

.............

DLL config & platform are: Active(Debug) & Active(Win32)

VB.NET config & platform are: Active(Debug) & Active(Any CPU)

Laptop Windows 10 is 64-bit

Change DLL platform to x64 ?

1
It yells pretty loudly off the screenshot: "No Common Language Runtime support". So adding a reference cannot work. The pinvoke declarations ought to be good enough, assuming you used extern "C" and declared them __stdcall. All you have to do is make sure that the myDll.dll file can be found at runtime. Do so by using Project > Add Existing Item > select the DLL. Set its "Copy to Output Directory" property to Copy if Newer.Hans Passant
Hans, can I just set the Visual-C++ DLL project properties > Common Language Runtime Support from "No..." to "Common Language Runtime Support" ? (Plus, the extern "C" __stdcall )Doug Null
It is not that easy, you have to write C++/CLI code. public ref class are essential keywords to get there.Hans Passant
Alas. Then am proceeding with below answer...Doug Null
Builds, but I get error when calling DLL: System.BadImageFormatException: 'An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)'Doug Null

1 Answers

4
votes

There's a difference between adding a reference to the DLL and P/Invoking it. You can only add a reference to .NET DLLs because it is a way of directly accessing the DLL's members in a .NET-friendly way. Since both assemblies are of the same language (IL) the DLL can easily be compiled and referenced by the regular application.

P/Invoking however is completely different because there you are marshalling calls to a native DLL, which is already compiled into pure machine code. It cannot be added as a reference because the compiler cannot link it to the .NET code since it only understands .NET languages and IL.

To add the DLL to your project you have to add it as a loose file instead:

  1. Right-click on your project in the Solution Explorer and go to Add > Existing Item....

    Add an existing item

  2. Locate your native DLL and select it (but do not add it). Then press the little arrow on the Add button and select Add As Link.

    • By adding the DLL as a link (shortcut) you always refer to the original file. Thus if you ever update/recompile the DLL you won't have to re-add it to your VB.NET project.

    Add you DLL as link

  3. Select your DLL in the Solution Explorer.

    Select the DLL in the Solution Explorer

  4. Go down to the Properties Window and change Copy to Output Directory to Copy always.

    • This will make sure that your DLL is always copied to the output directory (bin\Debug or bin\Release) every time you compile the project.

    Change Copy to Output Directory to Copy Always

  5. Done!

    Profit!