可以将对象作为参数传递给 Fortran 方法吗?

发布于 2024-09-16 10:49:12 字数 1340 浏览 7 评论 0原文

我目前正在努力将用 Fortran 编写的 DLL 导入到 Visual Basic 中。我已经掌握了所有基础知识,所以现在我正在尝试更进一步。标题基本上说明了一切,但我还是会解释一下我想要做什么。

对于踢腿和咯咯笑,我们假设我想传递一个包含三个双精度值的对象,可能代表三个维度空间中的一个点。在我的 Fortran 方法中,我想获取该对象,打印出 x 值,然后将 x 值更改为 7.5。这是我的 Fortran 代码,它就是这样做的。

module test
   type Point
      double precision x, y, z
   end type Point
end module test

function ex1(ThreeDubs)
   use test
   type (Point) :: ThreeDubs
   print *, ThreeDubs%x
   ex1 = 1
   return
end function

这段代码效果很好!...仅适用于结构。换句话说,假设我在 VB 中有以下结构和类,

Public Structure StructurePoint
   Public x As Double
   Public y As Double
   Public z As Double
End Structure

Public Class ObjectPoint
    Public x As Double
    Public y As Double
    Public z As Double
End Class

创建 StructurePoint 的实例会产生完美的结果:Fortran 方法打印出 x 值,然后修改 x 的值。完美的。现在问题来了。当我传递 ObjectPoint 的实例时,程序打印出类似于 1.523E-306 的值。基本上,告诉我它认为x值所在的位置不是x值。所以,这就是我的问题。是否有可能将对象传递给 Fortran DLL 并正确访问它,如果可以,我将如何去做?

解决方案

为了将此对象传递给 Fortran,唯一需要做的就是修改类声明。

<StructLayout(LayoutKind.Sequential)> _
Public Class CustomPoint3d
    Public x As Double
    Public y As Double
    Public z As Double
End Class

<DllImport("passPoint3d.dll")> _
Public Shared Function PrintX(ByVal point As CustomPoint3d) As Boolean
End Function

I'm currently working on being able to import a DLL written in Fortran into Visual Basic. I've got all the basics down, so now I'm trying to take it a step further. The title basically says it all, but I'll explain what it is I'm trying to do anyways.

For kicks and giggles, let's just assume I want to pass an object that has three double values in it, possibly representing a point in space in three dimensions. In my Fortran method, I want to take that object, print out the x value, then change the x value to 7.5. Here's my Fortran code that does just that.

module test
   type Point
      double precision x, y, z
   end type Point
end module test

function ex1(ThreeDubs)
   use test
   type (Point) :: ThreeDubs
   print *, ThreeDubs%x
   ex1 = 1
   return
end function

And this code works great!...For structures only. In other words, Let's assume I have the following structure and class in VB

Public Structure StructurePoint
   Public x As Double
   Public y As Double
   Public z As Double
End Structure

Public Class ObjectPoint
    Public x As Double
    Public y As Double
    Public z As Double
End Class

Creating an instance of StructurePoint yields perfect results: the Fortran method prints out the x value, and then modifies the value of x. Perfect. Now the problem. When I pass an instance of ObjectPoint, the program prints out a value similar to 1.523E-306. Basically, telling me that the location in which it thinks the x value is located is not the x value. So, herein lies my question. Is it even possible to pass an Object to a Fortran DLL and access it correctly, and if so, how would I go about doing so?

The Solution

Modifying the Class declaration is the ONLY thing that has to be done in order to pass this object to Fortran.

<StructLayout(LayoutKind.Sequential)> _
Public Class CustomPoint3d
    Public x As Double
    Public y As Double
    Public z As Double
End Class

<DllImport("passPoint3d.dll")> _
Public Shared Function PrintX(ByVal point As CustomPoint3d) As Boolean
End Function

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

┈┾☆殇 2024-09-23 10:49:12

这可能很困难,而且我认为没有任何好处,所以我建议你不要打扰!

无论如何,就这样吧!我认为 VB.Net 对象将被编组为指针。 Fortran 90 中对指针有一些支持。如果您添加,它可能会起作用指向 ThreeDubs 的 Fortran 声明的指针

function ex1(ThreeDubs) 
   use test 
   type (Point), pointer :: ThreeDubs ! Note additional pointer keyword
   print *, ThreeDubs%x 
   ex1 = 1 
   return 
end function 

我怀疑您能否从 Fortran 中调用 ThreeDubs 对象中的方法,因此我不确定传递对象的好处。

这里有两个两个 microsoft.com/en-us/magazine/cc163910.aspx" rel="nofollow noreferrer">有关 PInvoke 的文章: PInvoke 是调用老式“非托管”DLL(如 Fortran)的 .Net 名称。这些文章解释了 .Net 参数如何“编组”(翻译)到 Fortran DLL 中。您可以使用属性对编组进行一些控制:文章解释了更多。他们倾向于使用 C 和 C# 作为示例:(

This might be difficult, and I don't think there's any benefit, so I advise you not to bother!

Here goes anyway! I think the VB.Net object will be marshalled as a pointer. There is some support for pointers in Fortran 90. It might work if you add pointer to the Fortran declaration of ThreeDubs.

function ex1(ThreeDubs) 
   use test 
   type (Point), pointer :: ThreeDubs ! Note additional pointer keyword
   print *, ThreeDubs%x 
   ex1 = 1 
   return 
end function 

I doubt you would ever be able to call methods in the ThreeDubs object from the Fortran, so I'm not sure of the benefit of passing an object.

Here are two articles on PInvoke: PInvoke is the .Net name for calling oldschool "unmanaged" DLLs like your Fortran. The articles explain how .Net arguments are "marshalled" (translated) into the Fortran DLL. You have some control over the marshalling using attributes: the articles explain more. They tend to use C and C# for examples :(

甜警司 2024-09-23 10:49:12

我不了解 Visual Basic,但我在 Fortran 和 Fortran 之间共享用户定义类型。 C. Fortran 2003 的 ISO C 绑定支持此功能,Fortran 95 编译器已广泛支持该功能。您声明一个 Fortran 用户定义类型并为其指定绑定 C 属性和绑定名称。只要该类型的所有子组件都可以与 C 互操作,那么用户定义类型也可以与 C 互操作。并且这种方法是标准的和可移植的。我通过将 Fortran 用户定义类型变量作为模块变量传递信息,并通过在文件顶部声明将 C 结构变量置于全局内存中来完成此操作。也许您可以在 Fortran 端使用 ISO C 绑定,并以某种方式告诉 Visual Basic 使用类似 C 的接口?

I don't know about Visual Basic, but I've shared user-defined types between Fortran & C. This is supported by the ISO C Binding of Fortran 2003, which is already widely supported by Fortran 95 compilers. You declare a Fortran user-defined type and give it the bind C attribute and a bind name. As long as all of the sub-components of the type are inter-operable with C, then the user-defined type is also inter-operable with C. And this method is standard and portable. I've done this by passing the information with the Fortran user-defined type variable being a module variable, and the C structure variable being in global memory via being declared at the top of a file. Perhaps you can use the ISO C Binding on the Fortran side, and somehow tell Visual Basic to use a C-like interface?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文