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

Mixed Language issue (Accessing C structure from Fortran)

nitinshukla
Beginner
655 Views

Hi,

I have to access a C structure from Fortran using COMMON BLOCK. In my C program the structure's variable is shared for multiple process access using the #pragma directives. On the Fortran side I have defined a COMMON BLOCK to map on this C structure variable. I am trying to compile the code to build the DLL. The problem I face is the Linker gives me error as stating 'one or more multiply defined symbols found' for the structure variable declared. My code looks like this.

Code:
*********************** C code *************************

###### globalParams.h ########
#pragma pack(2)
	typedef struct CPPDLL_MACRO _GlobalParam {
		int k[2];
		float var;
		int l;
		char str[11];
	} GlobalParam;
#pragma pack()

	extern CPPDLL_MACRO GlobalParam globalParam;

###### globalParams.c ######
#pragma data_seg (".shared")
	GlobalParam globalParam = {0};
#pragma data_seg()

#pragma comment(linker, "/section:.shared,RWS")


******************** Fortran code *************************

###### Engine.FI #####
!DEC$ ATTRIBUTES ALIAS:'_globalParam' :: GLOBALPARAM
	COMMON /GLOBALPARAM/ K(2), VAR, L, STR
	INTEGER*4    K, L
	REAL*4       VAR
	CHARACTER*11 STR

###### INITIALIZEPARAMS.F ######
	SUBROUTINE INITIALIZEPARAMS
#include "Engine.FI"

	DATA K   / 5, 8 /
	DATA VAR / 2.30000 /
	DATA L   / 9 /
	DATA STR / "HELLO WORLD" /

	END SUBROUTINE

***********************************************************

I am trying to compile the above code to build a DLL but the linker gives me the following error.

Code:
Linking...
INITIALIZEPARAMS.OBJ : error LNK2005: _globalParam already defined in globalParameters.obj
INITIALIZEPARAMS.OBJ : warning LNK4006: _globalParam already defined in globalParameters.obj; second definition ignored
   Creating library Debug/CPPDLL.lib and object Debug/CPPDLL.exp
..inCPPDLL.dll : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

CPPDLL.dll - 2 error(s), 1 warning(s)

Can any one help me resolve this problem? Why is the Fortran COMMON BLOCK 'GLOBALPARAM' not mapping to the memory location of 'globalParam' structure defined in the C code?

Any help will be obliged. I am using CVF 6.6 and VC++ 6.0.

Nitin

Message Edited by nitinshukla on 02-28-2005 02:05 AM

0 Kudos
7 Replies
TimP
Honored Contributor III
655 Views
The globalParam objects defined in C and in Fortran should be duplicates. The linker is correct in telling you to use just one of them.
0 Kudos
Steven_L_Intel1
Employee
655 Views
In case Tim's use of the term "defined" is ambiguous, try "initialized". You can't initialize global storage (common) in more than one program unit.
0 Kudos
nitinshukla
Beginner
655 Views
Hi sblionel,
Thanks for the clearing the ambiguity. As you now understand what I am trying to achieve here, can you let me know how I can go about it. I want tokeep the global variable globalParam in a shared section of DLL inorder to share it across processes while at the same time want to intialize this parameterin Fortran. Is there a way to do this? Any help is obliged. Thanks.
Nitin
0 Kudos
Steven_L_Intel1
Employee
655 Views
Remove the " = {0}" from GlobalParams.c is I think what you need. I am not a C expert.

However, I am not sure this will work properly because Fortran will want to put the COMMON in the .data section. You may need to use a linker /section switch to specify RWS since Fortran does not have a directive to do this. In this case, remove GlobalParams.c entirely and use the linker switch.

Message Edited by sblionel on 03-01-2005 08:34 AM

0 Kudos
nitinshukla
Beginner
655 Views
Hi sblionel,
Thanks. You have been of great help. I tried the approach of sharing the .data section using the linker /section switch to specify RWS. But the linker gives warning LNK4092.It leads to the issues of relocation.
I thinkit will be better if the COMMON BLOCK data is directed to some user specfied section rather than .data. Thenuser defined section can be shared using same linker /section switch. This willspare mefrom sharing.data section from the DLL. I do not knowhow can I direct theCOMMON BLOCK data to user specified section in DLLusing FORTRAN. I know how to do this in C but don't know howCVF handles this.
Nitin

Message Edited by nitinshukla on 03-01-2005 09:41 PM

0 Kudos
Steven_L_Intel1
Employee
655 Views
There is no support in CVF for specifying the name of the data section for a common. See the SAMPLESDLLDLLEXP2 examples for an example of creating a write-shared common.
0 Kudos
durisinm
Novice
655 Views
Is there going to be a problem mapping C's char str[11] to Fortran's CHARACTER*11 STR? Doesn't Fortran pass a hidden string length variable before or after the string data?
Mike D.
0 Kudos
Reply