- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am playing, for a valid reason, with the grammar checker program LINK developed at Carn Mellon in about 2005. There is a later version but it does not play well with INTEL C or VS and the 2005 does what I want it to do for the moment.
The program runs quite nicely and well give me a 1 for a valid sentence and a 0 otherwise.
However, I want to add a Fortran subroutine to do a lot of hard lifting in a language I know how to code in - somewhat - and I have no desire to push my C knowledge beyond what it currently is - about Miss Scotman's first grade class level.
I have used the INTEL sample, but it is CPP, and the CM code is just pure old fashioned C.
I get a two  errors, Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol _for_CFI_establish referenced in function _main Baker C:\Users\macne\Documents\Visual Studio 2017\Projects\Program111 - Baker\Baker\Baker\AMain.obj : 1
and
Severity Code Description Project File Line Suppression State
Error LNK1120 1 unresolved externals Baker C:\Users\macne\Documents\Visual Studio 2017\Projects\Program111 - Baker\Baker\Debug\Baker.exe : 1
---------------------------------------------------------------------------------------------------------
from calling the Fortran subroutine, which in the Intel sample is in a CPP file.
I tried several alternatives Fortran calling C and it basically always breaks down on the use of C files, but I do not want to stuff with the things that are working.
I enclose the complete solution - but here is the main code for the C code calling the Fortran subroutine.
 
/********************************************************************************/
/* Copyright (c) 2004                                                           */
/* Daniel Sleator, David Temperley, and John Lafferty                           */
/* All rights reserved                                                          */
/*                                                                              */
/* Use of the link grammar parsing system is subject to the terms of the        */
/* license set forth in the LICENSE file included with this software,           */ 
/* and also available at http://www.link.cs.cmu.edu/link/license.html           */
/* This license allows free redistribution and use in source and binary         */
/* forms, with or without modification, subject to certain conditions.          */
/*                                                                              */
/********************************************************************************/
#include "link-includes.h"
#include "ISO_Fortran_binding.h"
void fsub
(int INT_ARG,
	CFI_cdesc_t *STR_IN,
	CFI_cdesc_t *STR_OUT
);
int main() {
    Dictionary    dict;
    Parse_Options opts;
    Sentence      sent;
    Linkage       linkage;
    char *        diagram;
    int           i, num_linkages;
    char *        input_string[] = {
       "Grammar is useless because there, is nothing to say -- Gertrude Stein.",
       "Computers are useless; they can only give you answers -- Pablo Picasso."};
	char instring[40];
	char outstring[40];
	int intarg;
	CFI_CDESC_T(0) instring_desc, outstring_desc; // Ignore warning for zero-sized array
	int status;
    opts  = parse_options_create();
    dict  = dictionary_create("4.0.dict", "4.0.knowledge", NULL, "4.0.affix");
    for (i=0; i<2; ++i) {
	sent = sentence_create(input_string[i], dict);
	num_linkages = sentence_parse(sent, opts);
	if (num_linkages > 0) {
	    linkage = linkage_create(0, sent, opts);
	    printf("%s\n", diagram = linkage_print_diagram(linkage));
	    string_delete(diagram);
	    linkage_delete(linkage);
	}
	sentence_delete(sent);
    }
    dictionary_delete(dict);
    parse_options_delete(opts);
	strcpy(instring, "Testing...");
	intarg = 123;
	/*
   Initialize descriptors. We'll set the length of the input string to the NUL-terminated length,
   which will be picked up by Fortran.
*/
	status = CFI_establish(
		(CFI_cdesc_t *)&instring_desc, // Descriptor
		&instring, // Base address
		CFI_attribute_other, // Not allocatable or pointer
		CFI_type_char, // Character type
		strlen(instring), // Element size
		0, // Number of dimensions (0 = scalar)
		NULL // Extents (not used here)
	);
	status = CFI_establish((CFI_cdesc_t *)&outstring_desc, &outstring, CFI_attribute_other, CFI_type_char, sizeof(outstring), 0, NULL);
	/* Call Fortran routine, passing descriptors. Note that intarg is passed by value */
	fsub(intarg, (CFI_cdesc_t *)&instring_desc, (CFI_cdesc_t *)&outstring_desc); 
	printf("%s\n", outstring); // Should print "Testing...0123"
    return 0;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Baker (the C++ project) doesn't link to the Fortran project's output library, so it's not pulling in the ifort run-time library. Ordinarily I would tell you to make FortranLib a dependent of Baker (which you should anyway), but Visual Studio won't pick up a Fortran output in a C++ project. Put the path to the .lib in Baker's Linker > Input > Additional Dependencies.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Baker (the C++ project) doesn't link to the Fortran project's output library, so it's not pulling in the ifort run-time library. Ordinarily I would tell you to make FortranLib a dependent of Baker (which you should anyway), but Visual Studio won't pick up a Fortran output in a C++ project. Put the path to the .lib in Baker's Linker > Input > Additional Dependencies.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It took a minute to work out to include the file name in the path.
Thanks it works a treat.
Just one wonders why we need to take that step.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As I wrote above, if you had made the Fortran_Lib project a dependent of Baker, then VS should have included the .lib in the link of Baker. But a few releases ago, Microsoft changed VS so that C++ projects dependent on non-C++ projects didn't do this. In addition, a C++ DLL project won't automatically link into a Fortran project (but a C++ LIB will.)
I'm surprised you didn't also get an error for the Fortran routine not being found.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I used the sample from Intel and worked backwards slowly, it took quite a few starts to get close.
How do I make the Fortan lib a dependence on the C++ program, I have no idea, I just followed the Intel example.
The C++ print function takes the 123 string and prints 00123 - which is interesting.
The idea is simple - construct a sentence from English words and see if it is a acceptable sentence then we do some other stuff.
it may work and it may not.
But it is fun just trying.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In a solution with more than one project, right click on the project you want to be the "parent" and select Build Dependencies > Project Dependencies. Check the box for the dependent project.
I don't see leading zeroes in the output when I try it. I would not expect those from the %i specifier.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, that worked.
Two leading zeros after Testing...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The programmer wrote
printf("%s\n", outstring); // Should print "Testing...0123"
next question - why does the VS IDE give errors on the standard strcpy type C functions.
I know this is Fortran -- but I think I have a better chance here than the C++ Forum. They are not as busy and the answers tend to terse.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You must be working from a different sample than I see, and I wrote this sample!
The C code in the Fortran_Calls_C sample has:
sprintf_s(output_text,output_text_len,"%s%i ",input_text,int_arg);There is no comment about what the output should be.
The reason that the compiler warns you about printf is that it is subject to buffer overflow safety issues. Therefore I put in sprintf_s, which passes the size of the output buffer rather than relying on the variables and formats to be the correct size.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just downloaded the zip file with Baker in it. The main c routine has the following form and the last lines show the printout of the results from the fsub routine.
/********************************************************************************/
/* Copyright (c) 2004                                                           */
/* Daniel Sleator, David Temperley, and John Lafferty                           */
/* All rights reserved                                                          */
/*                                                                              */
/* Use of the link grammar parsing system is subject to the terms of the        */
/* license set forth in the LICENSE file included with this software,           */ 
/* and also available at http://www.link.cs.cmu.edu/link/license.html           */
/* This license allows free redistribution and use in source and binary         */
/* forms, with or without modification, subject to certain conditions.          */
/*                                                                              */
/********************************************************************************/
#include "link-includes.h"
#include "ISO_Fortran_binding.h"
void fsub
(int INT_ARG,
	CFI_cdesc_t *STR_IN,
	CFI_cdesc_t *STR_OUT
);
int main() {
    Dictionary    dict;
    Parse_Options opts;
    Sentence      sent;
    Linkage       linkage;
    char *        diagram;
    int           i, num_linkages;
    char *        input_string[] = {
       "Grammar is useless because there, is nothing to say -- Gertrude Stein.",
       "Computers are useless; they can only give you answers -- Pablo Picasso."};
	char instring[40];
	char outstring[40];
	int intarg;
	CFI_CDESC_T(0) instring_desc, outstring_desc; // Ignore warning for zero-sized array
	int status;
    opts  = parse_options_create();
    dict  = dictionary_create("4.0.dict", "4.0.knowledge", NULL, "4.0.affix");
    for (i=0; i<2; ++i) {
	sent = sentence_create(input_string[i], dict);
	num_linkages = sentence_parse(sent, opts);
	if (num_linkages > 0) {
	    linkage = linkage_create(0, sent, opts);
	    printf("%s\n", diagram = linkage_print_diagram(linkage));
	    string_delete(diagram);
	    linkage_delete(linkage);
	}
	sentence_delete(sent);
    }
    dictionary_delete(dict);
    parse_options_delete(opts);
	strcpy(instring, "Testing...");
	intarg = 123;
	/*
   Initialize descriptors. We'll set the length of the input string to the NUL-terminated length,
   which will be picked up by Fortran.
*/
	status = CFI_establish(
		(CFI_cdesc_t *)&instring_desc, // Descriptor
		&instring, // Base address
		CFI_attribute_other, // Not allocatable or pointer
		CFI_type_char, // Character type
		strlen(instring), // Element size
		0, // Number of dimensions (0 = scalar)
		NULL // Extents (not used here)
	);
	status = CFI_establish((CFI_cdesc_t *)&outstring_desc, &outstring, CFI_attribute_other, CFI_type_char, sizeof(outstring), 0, NULL);
	/* Call Fortran routine, passing descriptors. Note that intarg is passed by value */
	fsub(intarg, (CFI_cdesc_t *)&instring_desc, (CFI_cdesc_t *)&outstring_desc); 
	printf("%s\n", outstring); // Should print "Testing...0123"
    return 0;
}I have not changed it - whilst you showed me how to fix the problem.
 
					
				
				
			
		
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page