Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

C Sharp Device

JohnNichols
Valued Contributor III
645 Views
Dear Intel:

I am not sure if Steve is back, but I will assume not.

I have a device that is called by C# code and I am stuck with the access to the data stream through C#.

I have tried to get the Fortran calls C to add an extension to C#.

http://support.microsoft.com/kb/828736 (this contains an error in creating the SNK file link)

using this standard for calling C# from C++. I got this to work, and then I got the C++ translated into the Fortran calls C module, but then I have compile errors.


The problem is that you have to register the DLL, which can do, but once I include the C# call inside the C called from the Fortran routine I get strange errors.

I would appreciate your thoughts on what are my errors and faults in the code.


Regards

JMN

I realise that I can call the C# from the C++ and then call the Fortran, but I prefer not to unless forced.


0 Kudos
10 Replies
jimdempseyatthecove
Honored Contributor III
645 Views
I am sure there is an easy way for you to eliminate the error...
Why not take the hard way....

Create a C++/C# application with no Fortran.
Create a Fortran application with noC++/C#

Have the Fortran Create(run) a process (your C++/C# application)
Connect the two in method of your choice

Memory Mapped File
Pipe
Messaging

Jim Dempsey
0 Kudos
JohnNichols
Valued Contributor III
645 Views
Jim:

I considered that and thought let us be pure. Purity has its costs.

But I have been reading further, the problem was I was reading all the stuff on C# and Fortran on the web and not reading the Intel manual. the manual helped a lot once I got past all the guff.

I finally worked out what the Fortran wizard was and generated the following module to call the registered DLL I had made. However I have not seen the $object before, I need help calling the module routine, my stuff gives a crash.

[bash]! Console1.f90 ! ! FUNCTIONS: ! Console1 - Entry point of console application. ! !**************************************************************************** ! ! PROGRAM: Console1 ! ! PURPOSE: Entry point for the console application. ! !**************************************************************************** program Console1 use sManagedDLL implicit none Real ret INTEGER(INT_PTR_KIND()) $OBJECT ! Variables ! Body of Console1 print *, 'Hello World' ret = ICalculator_Add( $OBJECT, 2, 3) end program Console1 [/bash]

Thanks

JMN
[bash]! sManagedDLL.f90 ! This module contains the Automation interfaces of the objects defined in ! B:UsersJohnDocumentsVisual Studio 2010ProjectssManagedDLLsManagedDLLbinDebugsManagedDLL.tlb ! Generated by the Fortran Module Wizard on 06/07/12 MODULE sManagedDLL USE IFWINTY USE IFAUTO IMPLICIT NONE ! CLSIDs TYPE (GUID), PARAMETER :: CLSID_Class1 = & GUID(#268EB429, #656C, #38F8, & CHAR('B1'X)//CHAR('37'X)//CHAR('C2'X)//CHAR('AA'X)// & CHAR('26'X)//CHAR('BA'X)//CHAR('DD'X)//CHAR('68'X)) TYPE (GUID), PARAMETER :: CLSID_ManagedClass = & GUID(#FABF2B8F, #5D04, #34E2, & CHAR('B1'X)//CHAR('2D'X)//CHAR('6D'X)//CHAR('C0'X)// & CHAR('10'X)//CHAR('D8'X)//CHAR('F3'X)//CHAR('08'X)) ! Module Procedures CONTAINS ! Error message routine SUBROUTINE $$DisplayError(invokeargs) USE USER32 IMPLICIT NONE ! Arguments INTEGER(4) invokeargs ! Error Variables INTEGER(2) code CHARACTER (LEN=256) :: source CHARACTER (LEN=1024) :: description CHARACTER (LEN=256) :: help_file INTEGER(4) help_context INTEGER(4) scode ! Local Variables CHARACTER (LEN=2048) ::msg CHARACTER (LEN=2048) ::msgtemp CHARACTER (LEN=1) ::lf INTEGER(4) ret lf = 'n'C ! Retrieve the error information CALL AUTOGETEXCEPTINFO (invokeargs, code, source, description, & help_file, help_context, scode) WRITE (msg, '(A, A, "Error code: 0x", Z8.8, A)') & TRIM(description), lf, scode, lf IF (source /= " ") THEN WRITE (msgtemp, '(A, "Source of error message: ", A, A)') & TRIM(msg), TRIM(source), lf msg = msgtemp END IF IF (help_file /= " ") THEN WRITE (msgtemp, '(A, "Help file: ", A, A)') & TRIM(msg), TRIM(help_file), lf msg = msgtemp END IF ! Display the message ret = MessageBox(NULL, TRIM(msg)//""C, "Automation Method Exception"C, & IOR(MB_ICONASTERISK , MB_OK)) END SUBROUTINE INTEGER(4) FUNCTION ICalculator_Add($OBJECT, Number1, Number2, $STATUS) !DEC$ ATTRIBUTES DLLEXPORT :: ICalculator_Add IMPLICIT NONE INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer !DEC$ ATTRIBUTES VALUE :: $OBJECT INTEGER(4), INTENT(IN) :: Number1 !DEC$ ATTRIBUTES REFERENCE :: Number1 INTEGER(4), INTENT(IN) :: Number2 !DEC$ ATTRIBUTES REFERENCE :: Number2 INTEGER(4), INTENT(OUT), OPTIONAL :: $STATUS ! Method status !DEC$ ATTRIBUTES REFERENCE :: $STATUS INTEGER(4), VOLATILE :: $RETURN INTEGER(4) $$STATUS INTEGER(INT_PTR_KIND()) invokeargs invokeargs = AUTOALLOCATEINVOKEARGS() CALL AUTOADDARG(invokeargs, '$RETURN', $RETURN) CALL AUTOADDARG(invokeargs, '$ARG1', Number1) CALL AUTOADDARG(invokeargs, '$ARG2', Number2) $$STATUS = AUTOINVOKE($OBJECT, 1610743808, invokeargs) IF ($$STATUS == DISP_E_EXCEPTION) CALL $$DisplayError(invokeargs) IF (PRESENT($STATUS)) $STATUS = $$STATUS ICalculator_Add = $RETURN CALL AUTODEALLOCATEINVOKEARGS (invokeargs) END FUNCTION ICalculator_Add END MODULE [/bash]
0 Kudos
JohnNichols
Valued Contributor III
645 Views
The C# Code is in the DLL is:

[bash]using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace sManagedDLL { public class Class1 { } // Interface declaration. public interface ICalculator { int Add(int Number1, int Number2); }; // Interface implementation. public class ManagedClass : ICalculator { public int Add(int Number1, int Number2) { return Number1 + Number2; } } } [/bash]

0 Kudos
JohnNichols
Valued Contributor III
645 Views
Dear Steve:

This complies but gives me an error

[bash]! Console1.f90 ! ! FUNCTIONS: ! Console1 - Entry point of console application. ! !**************************************************************************** ! ! PROGRAM: Console1 ! ! PURPOSE: Entry point for the console application. ! !**************************************************************************** program Console1 use IFCOM USE IFWINTY use sManagedDLL implicit none Real ret integer(4) status INTEGER(INT_PTR_KIND()) IA status = 111 ! Variables ! Body of Console1 print *, 'Hello World' write(*,*)status CALL COMCreateObjectByGUID (CLSID_Class1,CLSCTX_INPROC_SERVER,CLSID_ManagedClass,IA,status) write(*,*)status !ret = ICalculator_Add( IA, 2, 3) end program Console1 [/bash]
0 Kudos
Steven_L_Intel1
Employee
645 Views
John,

I will defer to users who have experience with C# and COM - that doesn't include me. Please understand that this is a user forum. While I and other Intel engineers do participate, we can't promise to provide help with all "how to" questions.

I do recall, though, that you need to call COMInitialize before any other COM calls, and then COMUnInitialize at the end.
0 Kudos
JohnNichols
Valued Contributor III
645 Views
Steve:

Thank you for your response. I fully appreciate your points, I was no where near as kind when I found out the device was accessed with C#. Unfortunately there are very few people in the world with Fortran and C# experience, anyone with anyengineering sensewould not access a device needing FFT analysis in C#, but I am stuck with it.

I need to compute a FFt every one second on multiple channels, which leaves Fortran or C++. I have FFT routines in C++ and Fortran, but I have tested the Fortran and I prefer stuff that has been properly proven to give the answer and not have to recalibrate the code.

I have slowly worked through the Intel Fortran manuals and actually I usually solve it by digging into the include files.

I have the code running albeit with some interesting errors, most I am sure I will solve,

But a question: what does warning 11077 mean? This is the C# routine I am trying to import, so why do I get a warning?

See below:

[bash]ipo: warning #11077: b:usersjohndocumentsvisual studio 2010ProjectsConsole1Console1DebugConsole1.obj: locally defined symbol __imp__SMANAGEDDLL_mp_ICALCULATOR_ADD imported 1> Creating library b:usersjohndocumentsvisual studio 2010ProjectsConsole1Console1DebugConsole1.lib and object b:usersjohndocumentsvisual studio 2010ProjectsConsole1Console1DebugConsole1.exp 1>Console1.obj : warning LNK4217: locally defined symbol _SMANAGEDDLL_mp_ICALCULATOR_ADD imported in function _MAIN__ 1>Embedding manifest...[/bash]
0 Kudos
Steven_L_Intel1
Employee
645 Views
This warning, which is the same as LNK4217, means that you have done a DLLIMPORT (either explicitly or implicitly) of a symbol that is defined in your own code. It can be ignored.

If you are computing FFTs, have you considered calling Intel MKL?
0 Kudos
JohnNichols
Valued Contributor III
645 Views
Steve:

In answer to your question: most probable route, I just do not like to fail, but until someone in Intel gives us a sample like this below I do not want to waste more time.

http://support.microsoft.com/kb/828736/c

Go and have a look at this microsoft sample, I have it running in C++ and C#. I would think it is not hard, as I have been trying to do in IVF. You have no samples from C# that I can find running.

The problem is down to two:

1. With the Fortran Module Wizard do I import all of the classes in the DLL or just the call to the routine I want to use.
2. this question depends on the answer to 1.

JMN
0 Kudos
Steven_L_Intel1
Employee
645 Views
You should need to import only the routines you want to use. I will take a look at the article you describe, but I do not know C#.
0 Kudos
JohnNichols
Valued Contributor III
645 Views
Steve:

I doubt this has anything to do with C#. I am making a mistake calling the Module created by the Intel Fortran Wizard.

Ifound this error which appears to be related:

There is a Statistics Package called R. It has a Fortran program to open R from Fortran. This program is shown at

http://rfortran.googlecode.com/svn-history/r21/trunk/src/RFortran_MedLevel.f90

The program includes acall to ComCreateObjectbyGUID just as I do below.


CALL COMCreateObjectByGUID (CLSID_Class1,CLSCTX_ALL,IID_ICalculator,IA,status)

write(*,*)IA

write(*,*)status

I get the same return error code as shown in the RProgram in Fortran.

[bash]! Initialise the COM Model call COMINITIALIZE(ok) if(ok/=0) then msg="COM architecture could not be initialised, ID:" // ok if(present(messOut))messOut=msg call message($error,msg); return end if ! Create call COMCREATEOBJECTBYGUID (rcom_CLSID_StatConnector, CLSCTX_ALL, IID_IStatConnector, R, ok) ! Create an instance of the R object if(ok/=0) then msg="Issue loading rcom.ID:"//ok selectcase(ok) case(-2147024732) ! strange bug with excessive commit stack size msg=trim(msg)//"(stack2big[commit]:reset<=450MB)" case(-2147024888) ! strange bug with excessive reserve stack size msg=trim(msg)//"(stack2big[reserve]:reset<=370MB)" case(-2147221164) ! happens if R did not have enough time to initialise msg=trim(msg)//"(R did not have time to open[increase'wait4R/wait4Rdef~5000'])" endselect if(present(messOut))messOut=msg call message($error,msg); return [/bash]
I get the message -2147221164, which is bizarre. RFortran is compiled on IVF as they include reference to the Intel Program.

So the problem is what is wrong with this call

CALL COMCreateObjectByGUID (CLSID_Class1,CLSCTX_ALL,IID_ICalculator,IA,status)

to the following Fortran Module Wizard Code

[bash]! sManagedDLL.f90 ! This module contains the COM interfaces of the objects defined in ! B:UsersJohnDocumentsVisual Studio 2010ProjectssManagedDLLsManagedDLLbinDebugsManagedDLL.tlb ! Generated by the Fortran Module Wizard on 06/08/12 MODULE sManagedDLL USE IFWINTY USE IFCOM IMPLICIT NONE ! CLSIDs TYPE (GUID), PARAMETER :: CLSID_Class1 = & GUID(#268EB429, #656C, #38F8, & CHAR('B1'X)//CHAR('37'X)//CHAR('C2'X)//CHAR('AA'X)// & CHAR('26'X)//CHAR('BA'X)//CHAR('DD'X)//CHAR('68'X)) TYPE (GUID), PARAMETER :: CLSID_ManagedClass = & GUID(#FABF2B8F, #5D04, #34E2, & CHAR('B1'X)//CHAR('2D'X)//CHAR('6D'X)//CHAR('C0'X)// & CHAR('10'X)//CHAR('D8'X)//CHAR('F3'X)//CHAR('08'X)) ! IIDs TYPE (GUID), PARAMETER :: IID_ICalculator = & GUID(#E7CED320, #79C2, #3976, & CHAR('8D'X)//CHAR('2D'X)//CHAR('B9'X)//CHAR('4D'X)// & CHAR('B5'X)//CHAR('61'X)//CHAR('1C'X)//CHAR('C0'X)) ! Interfaces INTERFACE INTEGER(4) FUNCTION ICalculator_Add($OBJECT, Number1, Number2, pRetVal) INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer !DEC$ ATTRIBUTES VALUE :: $OBJECT INTEGER(4), INTENT(IN) :: Number1 !DEC$ ATTRIBUTES VALUE :: Number1 INTEGER(4), INTENT(IN) :: Number2 !DEC$ ATTRIBUTES VALUE :: Number2 INTEGER(4), INTENT(OUT) :: pRetVal !DEC$ ATTRIBUTES REFERENCE :: pRetVal !DEC$ ATTRIBUTES STDCALL :: ICalculator_Add END FUNCTION ICalculator_Add END INTERFACE POINTER(ICalculator_Add_PTR, ICalculator_Add) ! routine pointer ! Module Procedures CONTAINS INTEGER(4) FUNCTION $ICalculator_Add($OBJECT, Number1, Number2, pRetVal) !DEC$ ATTRIBUTES DLLEXPORT :: $ICalculator_Add IMPLICIT NONE INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! Object Pointer !DEC$ ATTRIBUTES VALUE :: $OBJECT INTEGER(4), INTENT(IN) :: Number1 !DEC$ ATTRIBUTES REFERENCE :: Number1 INTEGER(4), INTENT(IN) :: Number2 !DEC$ ATTRIBUTES REFERENCE :: Number2 INTEGER(4), INTENT(OUT) :: pRetVal !DEC$ ATTRIBUTES REFERENCE :: pRetVal INTEGER(4) $RETURN INTEGER(INT_PTR_KIND()) $VTBL ! Interface Function Table POINTER($VPTR, $VTBL) $VPTR = $OBJECT ! Interface Function Table $VPTR = $VTBL + 28 ! Add routine table offset ICalculator_Add_PTR = $VTBL write(*,*) 'Here' $RETURN = ICalculator_Add($OBJECT, Number1, Number2, pRetVal) $ICalculator_Add = $RETURN END FUNCTION $ICalculator_Add END MODULE [/bash]

0 Kudos
Reply