Click here to Skip to main content
15,891,529 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hey,

I am working on my master thesis and need your help! Btw I am studying mechanical enginneering... so my programming skills are limited.

Here my problem:

I have a DLL, which is created in C# ( I cannot post it, because it is a part of an unpublished research). But it gives me some Arrays ( 1D-Array [], 2DArray[,] ).

For a simulation with ABAQUS I need to import that C#-DLL in C++ and/or FORTRAN.

I found the solution from Robert Giesecke to create a unmanaged DLL. I think this is the easiest solution for me. (Of course if someone has another solution for me, a wrapper or something, please post it)

Here my 1D Array example for a unmanaged C#-DLL created with R.Giesecke Template:

C#
using System;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace Testme
{
    class Test
    {

        [DllExport("Get1DArray", CallingConvention = CallingConvention.StdCall)]
        public static double Get1DArray([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] double[] STRESS, int i)
        {
            return STRESS[i];
        }

    }
}


and here my 2D Array code:

C#
using System;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace Testme
{
    class Test
    {

        public static int idx(int a, int b) { int cols = 2; return a * cols + b; }

        [DllExport("Set2DArray", CallingConvention = CallingConvention.StdCall)]
        public static int Set2DArray([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] STRAIN, int len)
        {
            STRAIN[idx(0, 0)] = 0;
            STRAIN[idx(0, 1)] = 1;
            STRAIN[idx(1, 0)] = 2;
            STRAIN[idx(1, 1)] = 3;
            STRAIN[idx(2, 0)] = 4;
            STRAIN[idx(2, 1)] = 5;

            return 0;
        }

    }
}


The Build have succeeded at both. How can I import the DLLs in C++ and/or FORTRAN?

Thx in advance!
Posted

C# DLL is not "unmanaged", it is managed. In CLI world, "DLL" or "EXE" is not that important; they are just assembly modules, the central concept is "assembly", which are made out of modules, usually only one (don't mix up modules and referenced assemblies).

With C#, the problem is pretty difficult. CLI is designed to easily use unmanaged code, but not to provide code for unmanaged modules. There are several approaches, let's consider them all.

  1. You can use C# to create a COM component and use this COM component in your Fortran code. I don't want even to consider this way, because it involves yet another obsolete technology in the indirect ad-hoc way. You can find a lot of information on COM-based approach.
  2. You can use intermediate project written in C++/CLI language. Even though it looks complex, this is actually the easiest way in many respects. You can do two things a) instead of using C# code, write the same code in C++/CLI; you can even automatically translate it; b) you can reference your C# assembly in some C++/CLI project, so you would need to use C#, C++/CLI and Fortran in solution. In both cases, you have to create a mixed-mode (managed + unmanaged) C++/CLI project. You can wrap your .NET classes/structures in some unmanaged methods and export them as in regular unmanaged DLL. Such mixed-mode modules can be two-fold: for other .NET assemblies they can function exactly as the usual .NET assembly, for unmanaged modules, they can look as regular unmanaged DLL with some exported function.

    Again, this approach looks complex (two languages!), but it is the simplest in one aspect: it requires the least knowledge of delicate detail of programming technologies.

    Please see:
    http://en.wikipedia.org/wiki/C%2B%2B/CLI[^],
    http://www.gotw.ca/publications/C++CLIRationale.pdf[^],
    http://www.ecma-international.org/publications/standards/Ecma-372.htm[^].
  3. There is another approach, which I actually like the most, but it requires really deep understanding of the inner machinery. Most people will even tell you this is impossible.

    The idea is: the standard on CLR does allow direct export of managed code to unmanaged, but this is not available in most languages like C#. IL itself allows such exports. The idea is: mark some separate methods which can be exported (static ones of course) with some attribute, disassemble your IL code which you obtained from the C# compiler, adjust disassemble code to add exports to unmanaged for the marked methods and assemble the modified code again. You will obtain the module which can be uses as a mixed-mode module explained in the previous item, so it could be used by your Fortran code. All this can be done in a fully automated way, with the build code which can be a custom step of some of your projects.

    For further detail, please see my past answers (they are all based on some advanced CodeProject articles I referenced):
    API's in .Net: Managed or UnManaged Code[^],
    Call Managed DLL written in C# from Unmanged Code VC++[^],
    How can I use a dll created in Visual Basic 2008 in Visual Basic 6.0[^],
    loading C# DLL in MFC[^].


Are you asking which approach I would use in your case? None of them. First of all, I would think of inverting the situation. I would try to stop writing Fortran application and convert all Fortran code to Fortran DLLs. And then I would use those Fortran DLLs in some .NET and/or some unmanaged applications. And I strongly, strongly advise you to move in this direction. Avoid solving unnatural problems.
 
Share this answer
 
v5
Thanks for your quick and detailed reply Sergey!

Yes, I know that the C# code is normally managed. By using the template of R. Giesecke makes it possible to create a unmanaged DLL. I am not sure, but i think it based on point 3 you described.
After building the C# Dll with R. Giesecke Teemplate, I get a .dll and a .lib file. Both are files, I need to implement my DlLL in Fortran. But I do not have an idea how to call that DLL from FOrtran or C++.


My problem is, that I cannot find a example to pass an array from C# to C++ / Fortran. No matter what approach ( COM, C++/CLR wrapper or R.Giesecke Template ). I can hardly imagine that I am the first who standing in front of this problem.

I have to use Fortran or C++. The plan is to use a subprogram in the mechanical simulation program ABAQUS. For this subprogram only Fortran can be used. The newes version of ABAQUS also support C++. But they used Fortran for 25 years. Bo idea whether the latest version really works with C++ well...
 
Share this answer
 
Comments
George Jonsson 29-Jun-14 1:46am    
Sounds like you are a bit stuck on the term c#.
If your code is successfully transformed to an unmanaged DLL, you can treat it as a standard Win32 DLL. So you should look for how to use a method in a Win32 DLL from Fortran.
This link might help you.
https://software.intel.com/en-us/forums/topic/278937

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900