2

I'm looking for a way to remove some header file dependencies. I'm working on a test project which runs a Windows UI in C# on a backend written in LabVIEW compiled to a DLL. Right now, I compile the LabVIEW code to a DLL, then write a middle layer in C++ which imports the LabVIEW DLL, compile the middle layer then import it in the C# project. I have had success testing a different case where the backend is purely C++, but the LabVIEW DLL brings in other dependencies from LabVIEW itself, so that when I try and run the top layer in C#, I get a "cannot find dependency error" in Visual Studio.

I have done some searching and it looks like using forward declaration in my middle layer cpp file is the way to go, but I am unclear about how to make this work. First off, can I do forward declaration since I am not using any pointers or classes at all in my example? If I cannot, what other way can I break the dependencies in my middle layer? I have also tried changing the compiler options of the middle layer DLL to multithread (/MT) as per this post's advice, but that did not resolve the dependency issue.

My test project is a very simple calculator app which does addition and subtraction. The core arithmetic code is written in LabVIEW and the GUI is written in WinUI. The LabVIEW code is as follows,

enter image description here

enter image description here

I then compile my LabVIEW project into a DLL, which also gives me the following header,

LV_calc.h

#include "extcode.h"
#ifdef __cplusplus
extern "C" {
#endif

/*!
 * AddTwoDbls
 */
double __cdecl AddTwoDbls(double x, double y);
/*!
 * SubtractTwoDbls
 */
double __cdecl SubtractTwoDbls(double x, double y);

MgErr __cdecl LVDLLStatus(char *errStr, int errStrLen, void *module);

void __cdecl SetExecuteVIsInPrivateExecutionSystem(Bool32 value);

#ifdef __cplusplus
} // extern "C"
#endif

Note the #include "extcode.h", which is the LabVIEW dependency located in the LabVIEW program files.

My interface currently loads the LabVIEW header and here is where I suspect I should be doing some forward declaration, but am unsure how. At present, the interface is as follows,

LVcalculatorInterface.h

#pragma once

#ifdef  LVCALCINTERFACE_EXPORTS
#define LVCALCINTERFACE_API __declspec(dllexport)
#else
#define LVCALCINTERFACE_API __declspec(dllimport)
#endif

// import and write new interfaces for LV functions
extern "C" LVCALCINTERFACE_API double LVaddDbls (double a, double b);

extern "C" LVCALCINTERFACE_API double LVdiffDbls(double a, double b);

LVcalculatorInterface.cpp

#include "LVcalculatorInterface.h"
#include "pch.h"
#include "LVbuilds/LV_calc.h"

double LVaddDbls(double a, double b) {
    return AddTwoDbls(a, b);
}

double LVdiffDbls(double a, double b) {
    return SubtractTwoDbls(a, b);
}

Finally, the compiled interface DLL is imported in the C# project

MainWindow.xaml.cs

namespace MyCalculator
{
    public class SimpleMathLV
    {
        [DllImport(@"Interface\LVcalcInterface.dll")]
        public static extern double LVaddDbls(double a, double b);
        [DllImport(@"Interface\LVcalcInterface.dll")]
        public static extern double LVdiffDbls(double a, double b);
    }

    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void Add_Button(object sender, RoutedEventArgs e)
        {
            double sum = SimpleMathLV.LVaddDbls(val_a.Value, val_b.Value);
            string sum_string = sum.ToString();
            Result.Text = sum_string;
        }

        private void Subtract_Button(object sender, RoutedEventArgs e)
        {
            double sum = SimpleMathLV.LVdiffDbls(val_a.Value, val_b.Value);
            string sum_string = sum.ToString();
            Result.Text = sum_string;
        }
    }
}

The C# app runs but throws an error when I interact with one of the UI buttons that calls the interface DLL. I get the message,

System.DllNotFoundException: 'Unable to load DLL 'Interface\LVcalcInterface.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)'

So in summary, I need a way to remove the LabVIEW dependency. I think forward declaration may be the solution, but how do I do forward declaration in this situation? Are there other ways I can safely remove the LabVIEW dependency?

MoogsDoog
  • 53
  • 4
  • I don't think the LabView dependency is necessarily the problem. Is the DLL actually in `\Interface\LVcalcInterface.dll` (most likely relative to the C# exe's directory)? You could use [ProcMon](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon) to see which paths are searched for to find the DLL. If the DLL is actually there, maybe you are compiling the DLL as 32 bit code, but the C# project is compiled as 64 bit (or AnyCPU)? You could also use [DependencyWalker](https://www.dependencywalker.com/) to check your DLL; maybe you need some LabView DLL next to it? – Sedenion Oct 21 '22 at 16:30
  • Thanks for the ideas Sedenion. The DLL is definitely there, I've done this with the absolute path to where the DLL was originally compiled and get the same error. I've also successfully imported other DLLs into this project no problem. As for 32 vs. 64 bit code, I checked this at one point also to make sure everything, including the LabVIEW DLL, is all 64 bit and they are. There may be a LabVIEW lib file I can add to my C# project, so I will try that next. – MoogsDoog Oct 21 '22 at 16:59
  • But even if there is a LabVIEW file I could add to my C# project, is there no way to remove that dependency in the first place, or am I stuck with it? – MoogsDoog Oct 21 '22 at 17:00
  • If the LabView lib file is a static library (and does not require a DLL), linking to it in your C++ DLL should be all that is needed. No need to add anything to LabView in your C# project. But if the lib file is actually an import library, i.e. is accompanied by a LabView DLL, then you need that DLL, too. In any case, have you tried ProcMon? It is usually a good way to get more information why a DLL is not loaded. – Sedenion Oct 21 '22 at 17:09

0 Answers0