Click here to Skip to main content
15,900,108 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello,
I am trying to integrate 2 systems together, the first system is built on FORTRAN and C, the second system is .NET.
In the first system, FORTRAN code calls subroutines, I am trying to build a .NET dll to replace some of the FORTRAN subroutines, so I found that the best way to do it is to create a wrapper in C/C++, this wrapper is a set of extern C functions that will get called by FORTRAN, these functions pass the parameters from FORTRAN to .NET, since all parameters are passed by reference, FORTRAN should get the new values.

Well, it's not that simple, FORTRAN passes char* to C, which is unmanaged type, string in C also is not managed so I can't pass it to .NET, because .NET expects managed types.

I am not so familiar with datatype conversions between different platforms, so what I need to achieve is one of the following:
1- Find a way to link .NET dll with FORTRAN, .NET subroutines should be globally exposed, so that FORTRAN should be able to call them directly without the need to create objects.
OR
2- Find a way to pass unmanaged string from C/C++ to VB.NET dll, so that FORTRAN should be able to have a reference to the variables (with the correct encoding).

I Apologize if my previous explanation doesn't make sense to some of the readers, I know .NET, but this is my first C/C++ program, I'm not familiar with the old stuff at all.

I'll try to explain more..., what I need is a an extern C subroutine that has tow parameters (char* , int), this subroutine should convert the char* to a managed type and pass it by reference to a .NET subroutine, the .NET sub should change the value of the parameter.
Now the C subroutine needs to convert the managed type (that is returned from .NET) to unmanaged type and put the new value in the original character array, so that FORTRAN can get the new value!

Please help.
Thanks
Posted
Comments
Philippe Mori 20-Feb-13 23:14pm    
Is your code to complex to require an intermediate layer between Fortran and VB.NET. Because, if your Fortran code uses conventions and type that are similar to those in the Windows API, you might be able to directly call C code using P/Invoke. This should be able to handle string convertion automatically provided that you uses the appropriate attributes.

Using C++ in between is much more powerfull but if it is not necessary, then it make your system more complex (1 extra DLL).
Sameer Alomari 21-Feb-13 9:44am    
It is complex legacy code, the system is 25 years old, I am not allowed to touch the FORTRAN code because many other systems rely on it, but if there is a way to expose .NET subroutines to be called by FORTRAN without creating an object from the .NET class, then I don't need the intermediate layer.
Philippe Mori 21-Feb-13 11:41am    
By the way, what are the depedencies of your DLL. I was assuming that Fortran DLL depends on C++ DLL which then dépends on VB.NET DLL.

But if is the other way (CB.NET --> C++ --> Fortran, then it will changes somehow the implementation).
Philippe Mori 21-Feb-13 11:59am    
Please add some examples that shows us pertinent code (and also the type of C++ DLL you are building. Is it managed). There are so much possibilities that it is hard to help you if we don't know what you are trying.

Your C++ DLL should be compiled in mixed mode (/clr). C++/CLI will allows you to uses both regular C/C++ and .NET managed types.

Your C++/CLI DLL should be callable from Fortran (assuming that your properly export C style functions) and it should be able to call VB.NET code (provided the assembly can be found but you can hook into that if necessary).

You can also go in the other direction using callbacks and proper conversion.

For more information, you can uses Google. A few links:

http://msdn.microsoft.com/en-us/library/ms973872.aspx[^]

Calling Managed Code from Unmanaged Code and vice-versa[^]
 
Share this answer
 
Comments
Espen Harlinn 20-Feb-13 20:27pm    
5'ed!
Sameer Alomari 21-Feb-13 10:01am    
My C++ code is callable from FORTRAN, my problem is passing the parameters from C++ to VB.NE, string in C is unamaged and can't be passed to .NET, I tried different types like CString , CStringA, etc, but I found that it is not compatible with FORTRAN and the data comes back "corrupted from the .NET dll
Philippe Mori 21-Feb-13 11:56am    
In C++/CLI, you can easily convert C-style string to .NET managed System::String and it is a bit more works to go in the other direction.

Also, the solution is highly dependent on how the memory is handled. Typically, strings should be desallocated using the same run-time that was used for allocation.
Sameer Alomari wrote:
No, We need the DLL to be .NET, the purpose of doing this is to start migrating the system to .NET, step by step, and function by function.
Not really. You also can use native (unmanaged) DLL. There are two ways: using P/Invoke or using mixed-mode C++/CLI project (managed + unmanaged) which you can use to produce a DLL module, to be used as a regular .NET assembly which can be referenced by your .NET assembly.

I described these two approaches in my past answers:
Dealing with windows form application[^],
How to invoke C++ DLL in ASP.NET?[^].

—SA
 
Share this answer
 
Comments
Espen Harlinn 20-Feb-13 20:27pm    
5'ed!
Sergey Alexandrovich Kryukov 20-Feb-13 20:35pm    
Thank you, Espen.
—SA
>> I'm not familiar with the old stuff at all
Hmm, I was reading along, somewhat sympathetic to your plight - and here I nearly lost any interest ...

Which fortran compiler are you using? Intel,GNU, other? This is important because there is something that is called a "calling convention" that might differ between the compilers: Calling convention[^]

Now, if you are using the Intel compiler:

In C and C++, you can specify the __stdcall calling convention by using the __stdcall keyword in a function definition. This is the calling convention used to call most of the Windows API functions.

The following C language function definition allows you to call to a fortran subroutine using the __stdcall calling convention:
extern void __stdcall CALCULTE_SOMETHING_IN_FORTRAN (int n); 


There is also the ATTRIBUTES directive, which allows a fortran subroutine to be called using the c calling convention:
SUBROUTINE CALCULTE_SOMETHING_IN_FORTRAN (I)
  !DEC$ ATTRIBUTES C :: CALCULTE_SOMETHING
  INTEGER I


Here is a link you may find useful:
Fortran/MASM Calling Conventions[^] - so that you get the idea about why calling conventions matter ...

As for:No, We need the DLL to be .NET, the purpose of doing this is to start migrating the system to .NET, step by step, and function by function

If the code works, why on earth would you do someting like that?


Best regards
Espen Harlinn
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 20-Feb-13 20:44pm    
Useful detail.., a 5.
—SA
Will it be more convenient to you if you send all parameters as strings and then interpret them from the c++ / .NET application? You can pack as many arguments as you like, using separators such as "#" and send them as a single parameter.
 
Share this answer
 
Comments
Sameer Alomari 20-Feb-13 15:03pm    
I am not allowed to change the FORTRAN Code, it is a legacy code and bunch of other systems work with it, so it is not possible.
Also as I said, you can't pass std::string to .NET because .net expects System::String
Sergey Alexandrovich Kryukov 20-Feb-13 15:24pm    
Can you develop DLLs with FORTRAN? It will resolve the problem.
—SA
Sameer Alomari 20-Feb-13 15:31pm    
No, We need the DLL to be .NET, the purpose of doing this is to start migrating the system to .NET, step by step, and function by function

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