locked
Use DLL (delphi) in C# with Visual Studio RRS feed

  • Question

  • Hello,

    I have a dll created with delphi language (Borland Delphi 7) which thus contains functions in delphi which I would like to use in C# with Visual Studio 2017.

    I want to use for example the GENERATE_FILE function contained in test.dll.

    Delphi code :

    procedure GENERATE_FILE(Path, Input_File : AnsiString); stdcall;
    
    procedure GENERATE_FILE(Path, Input_File : AnsiString); stdcall;
    
    var
    
    begin
    
    …
    
    GENERATE_CALC(Path_And_File, CRC32, Total, err);
    
    …
    
    end;


    In C#, I want to use the function GENERATE_FILE contained in test.dll but what is the type of the parameters Path and Input_File in C# ?

    Below is an example of C# code I made to use test.dll in C#. I set string as a type for parameters of the function GENERATE_FILE.

    namespace AppTest
    
    {
    
        Public class Program
    
        {
    
            [DllImport("test.dll", CharSet = CharSet.Ansi)]
    
            public static extern bool CREATE_FILE(string pathDirectory, string filename);
    
            static void Main(string[] args)
    
            {
    
                GENERATE_FILE(@"C:\Users", "file.txt");
    
            }
    
        }
    
    }


    I added the test.dll in Visual Studio by right clicking on the project then add an existing element, then, in the properties of the test.dll, I put "Content" in Generation action and I put "Always copy "(output directory). When I run the solution, I have the test.dll in bin\Debug.

    But when I test this program, I get the following error at the line that contains:

    GENERATE_FILE(@"C:\Users", "file.txt");

    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '

    How to solve this problem ?

    I think the issue is about the type of parameters in the function GENERATE_FILE. What are the type equivalents between delphi and C# for the function GENERATE_FILE ?

    Thank you for your help.


    • Edited by speed780 Thursday, April 30, 2020 12:41 AM
    Thursday, April 30, 2020 12:30 AM

All replies

  • Hello,

    I have a dll coded in delphi language which thus contains functions in delphi which I would like to use in C# under Visual Studio 2017.

    I want to use for example the GENERATE function contained in test.dll.

    Below is an example of C# code I made to use test.dll in delphi in C#.

    namespace AppTest
    {
        Public class Program
        {
            [DllImport("test.dll", CharSet = CharSet.Ansi)]
            public static extern bool GENERATE(string path);
    
            static void Main(string[] args)
            {
                GENERATE(@"C:\Users");
            }
        }
    }
    


    But when I test this program, I get the following error:

    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '

    How to solve this problem ?

    I placed test.dll in the folder that contains the C# source files.

    How C# is able to read a dll in delphi if Visual Studio does not know delphi?

    Thank you for your help.

    Wednesday, April 29, 2020 9:33 AM
  • Make sure the dll is the folder the app is running from.  If running through visual studio it is probably bin/debug or bin/release in the folder your solution is in
    • Proposed as answer by CoolDadTx Wednesday, April 29, 2020 2:05 PM
    Wednesday, April 29, 2020 9:38 AM
  • Hello,

    Did you copy this file next to your "exe"? You can manually copy or automatically. Select that file on Visual Studio, and in properties (generally F4 key) set "copy to local" to "true" than it will do it for your.

    The second questions answer is Interoperability. Read this : https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interop/interoperability-overview 


    www.cihanyakar.com




    • Edited by Cihan YakarMVP Wednesday, April 29, 2020 9:45 AM
    • Proposed as answer by CoolDadTx Wednesday, April 29, 2020 2:11 PM
    Wednesday, April 29, 2020 9:41 AM
  • Yes, I did it. It generates test.dll in bin/debug but I have always the error message:

    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '

    How to fix this issue, please?

    Wednesday, April 29, 2020 10:31 AM
  • Yes, I did it. It generates test.dll in bin/debug but I have always the error message:

    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '

    How to fix this issue, please?

    Strange,

    Maybe it depends another dll. You can check it via dumpbin /DEPENDENTS

    https://docs.microsoft.com/en-us/cpp/build/reference/dependents?view=vs-2019

    Another maybe, you may have changed the probing path.https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/probing-element

    Maybe..., convert your application target "any cpu" to "x86"

    Latest; the dll may corrupted.


    www.cihanyakar.com

    Wednesday, April 29, 2020 12:14 PM
  • As Ken and Cihan mentioned the DLL must be in the output folder of your C# project, not where the source files are. When you create a typical C# app it'll auto generate a bin\debug for when you build your code in debug mode. The DLL you want to call needs to be in that bin\debug folder. In release mode it'll be bin\release.

    Personally I recommend that you create a folder in your project called Dependencies or Libraries or something. Put the DLL in there. You'll likely need to alter your source control exclusion rules to allow this folder to to be checked into source control. 

    Then use a post build event to copy the binary(ies) from this folder to your output folder at build time. Something like this works.

    xcopy "$(ProjectDir)dependencies" "$(TargetDir)" /Y /R /S /I

    You set this in the project properties. After a successful build it copies the contents of Dependencies (or whatever) into the output directory. Do this for all your project configurations and it should then be able to load.

    Also note that your Delphi DLL is probably x86 so ensure your console app has the project property Prefer 32 bit set or change the project platform to always be x86 otherwise it'll fail at runtime with a bad format. You cannot load 32-bit DLLs into 64-bit processes.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, April 29, 2020 2:11 PM
  • Thank you for your help.

    I'm going to tell more detail about the problem.

    I have a dll created with delphi language (Borland Delphi 7) which thus contains functions in delphi which I would like to use in C# under Visual Studio 2017. It is a native dll.

    I want to use for example the GENERATE_FILE function contained in test.dll.

    Delphi code :

    procedure GENERATE _FILE(Path, Input_File : AnsiString); stdcall; procedure GENERATE _FILE(Path, Input_File : AnsiString); stdcall; var ...

    begin … GENERATE_CALC(Path_And_File, CRC32, Total, err); … end;


    In C#, I want to use the function GENERATE_FILE contained in test.dll but what is the type of the parameters Path and Input_File in C# ?

    Below is an example of C# code I made to use test.dll in delphi in C#. I set string as a type for parameters of the function GENERATE_FILE.

    namespace AppTest
    {
        Public class Program
        {
    
            [DllImport("test.dll", CharSet = CharSet.Ansi)]
    
            public static extern bool CREATE_FILE(string pathDirectory, string filename);
    
            static void Main(string[] args)
            {
                GENERATE_FILE(@"C:\Users", "file.txt");
            }
        }
    
    }


    I added the test.dll in Visual Studio by right clicking on the project then add an existing element, then, in the properties of the test.dll, I put "Content" in Generation action and I put "Always copy "(output directory). When I run the solution, I have the test.dll in bin\Debug.

    But when I test this program, I get the following error at the line that contains:

    GENERATE_FILE(@"C:\Users", "file.txt");

    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '

    How to solve this problem ?

    I think the issue is about the type of parameters in the function GENERATE_FILE. What are the type equivalents between delphi and C# for the function GENERATE_FILE ?

    Thank you for your help.

    Thursday, April 30, 2020 1:20 AM
  • It is not a parameter problem, yet. If it were a parameter problem then you'd get a runtime error about the stack. The error you're getting indicates it cannot load the DLL. That means either it isn't finding the DLL or it is missing a dependency. As Cihan mentioned you can run a depends to see what other DLLs it relies on. All the DLLs needed by the Delphi DLL have to be accessible otherwise it will fail to load.

    Once you get the DLL loading you're going to find the rest of the DllImport is probably not right. For example a C# bool won't work in most native code. Your Delphi call doesn't seem to have a return type so it should be void in the extern call as well. Additionally the calling convention used in Delphi is stdcall. You need to set the CallingConvention to stdcall in the DllImport otherwise the stack will get corrupted.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, April 30, 2020 2:27 AM
  • Hi speed780,
    About the error, I have some suggestions you can refer to.
    1.You can try to enter the full-path of the dll.
    2.Check the dependencies of the DLL.
    You can use the dumpbin tool to find out the required DLL dependencies:

    dumpbin /DEPENDENTS test.dll

    3.Make sure you set the Build Platform Target to x86 or x64 and choose Prefer 32 bit.
    4.The Delphi ABI differs from the Microsoft ABI for certain types.(what you pointed).The Delphi ABI translates a managed return type into a hidden var parameter.
    More details you can refer these threads.
    [Using Delphi DLL in C#]
    [C# calling dll file of Delphi]
    [Unable to load DLL (Module could not be found HRESULT: 0x8007007E)]
    Hope these are helpful to you.
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, April 30, 2020 3:06 AM