在C ++ / FORTRAN中使用非托管C#-DLL [英] Using unmanaged C#-DLL in C++/FORTRAN

查看:97
本文介绍了在C ++ / FORTRAN中使用非托管C#-DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,



我正在研究我的硕士论文并需要你的帮助!顺便说一下我正在学习机械工程......所以我的编程技巧有限。



这里我的问题:



我有一个用C#创建的DLL(我不能发布它,因为它是未发表的研究的一部分)。但它给了我一些数组(1D-Array [],2DArray [,])。



对于使用ABAQUS的模拟我需要在C ++中导入C#-DLL和/或FORTRAN。



我找到了Robert Giesecke的解决方案来创建一个非托管DLL。我认为这对我来说是最简单的解决方案。 (当然,如果有人为我提供了另一种解决方案,包装或其他东西,请发布)



这里是用R创建的非托管C#-DLL的一维数组示例.Giesecke模板:



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:

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];
        }

    }
}





和这里我的2D数组代码:





and here my 2D Array code:

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;
        }

    }
}





Build在两者都取得了成功。如何在C ++和/或FORTRAN中导入DLL?



提前Thx!



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

Thx in advance!

推荐答案

C#DLL不是非托管,它是托管的。在CLI世界中,DLL或EXE并不那么重要;它们只是组装模块,中心概念是组装,它由模块组成,通常只有一个(不要混淆模块和参考组件)。



使用C#,问题非常困难。 CLI旨在轻松使用非托管代码,但不为非托管模块提供代码。有几种方法,让我们考虑一下。



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. 您可以使用C#创建COM组件并在Fortran代码中使用此COM组件。我甚至不想考虑这种方式,因为它涉及间接临时方式的另一种过时技术。您可以找到有关基于COM的方法的大量信息。
  2. 您可以使用以C ++ / CLI语言编写的中间项目。即使它看起来很复杂,但实际上这在许多方面都是最简单的方法。你可以做两件事a)而不是使用C#代码,在C ++ / CLI中编写相同的代码;你甚至可以自动翻译它; b)您可以在某些C ++ / CLI项目中引用您的C#程序集,因此您需要在解决方案中使用C#,C ++ / CLI和Fortran。在这两种情况下,您都必须创建混合模式(托管+非托管)C ++ / CLI项目。您可以将.NET类/结构包装在一些非托管方法中,并将它们导出为常规非托管DLL。这样的混合模式模块可以是双重的:对于其他.NET程序集,它们可以像通常的.NET程序集一样运行,对于非托管模块,它们可以看起来像具有一些导出功能的常规非托管DLL。



    同样,这种方法看起来很复杂(两种语言!),但它在一个方面是最简单的:它需要对编程技术细节的了解最少。



    请参阅:

    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. 还有另一种方法,我实际上最喜欢它,但它需要对内部机器有深刻的理解。大多数人甚至会告诉你这是不可能的。



    这个想法是:CLR上的标准确实允许将托管代码直接导出为非托管代码,但这不可用于大多数语言如C#。 IL本身允许这样的出口。这个想法是:标记一些可以导出的单独方法(当然是静态的)和一些属性,反汇编你从C#编译器获得的IL代码,调整反汇编代码,为未标记的方法添加导出以及组装修改后的代码代码再次。您将获得可用作前一项中说明的混合模式模块的模块,因此您的Fortran代码可以使用它。所有这些都可以通过完全自动化的方式完成,构建代码可以是某些项目的自定义步骤。



    有关详细信息,请参阅我的过去的答案(它们都基于我引用的一些高级CodeProject文章):

    .Net中的API:托管代码或非托管代码 [ ^ ],

    调用用C#编写的管理DLL来自Unmanged Code VC ++ [ ^ ],

    如何在Visual Basic 6.0中使用Visual Basic 2008中创建的dll [ ^ ],

    在MFC中加载C#DLL [ ^ ]。
  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[^].





您是否在询问我将采用哪种方法?他们都不是。首先,我想考虑改变这种情况。我会尝试停止编写Fortran应用程序并将所有Fortran代码转换为Fortran DLL。然后我会在某些.NET和/或一些非托管应用程序中使用这些Fortran DLL。我强烈建议你朝着这个方向前进。避免解决不自然的问题。



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.


感谢您快速而详细的回复谢尔盖!



是的,我知道C#代码是通常管理。通过使用R. Giesecke的模板,可以创建一个非托管DLL。我不确定,但我认为它基于你描述的第3点。

用R. Giesecke Teemplate构建C#Dll之后,我得到了一个.dll和一个.lib文件。两者都是文件,我需要在Fortran中实现我的DlLL。但我不知道如何从FOrtran或C ++调用该DLL。





我的问题是,我找不到将数组从C#传递给C ++ / Fortran的示例。无论采用何种方法(COM,C ++ / CLR包装或R.Giesecke模板)。我很难想象我是第一个站在这个问题面前的人。



我必须使用Fortran或C ++。计划是在机械模拟程序ABAQUS中使用子程序。对于此子程序,只能使用Fortran。 ABAQUS的新版本也支持C ++。但他们使用Fortran已有25年了。 Bo认为最新版本是否真的适用于C ++ ......
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...


这篇关于在C ++ / FORTRAN中使用非托管C#-DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆