Is it possible to modify compiler include path for Dymola? - c

This question is raised due to a situation that I encountered
Say I have these external files and some declarations or definitions in them:
foo1.h
extern void ext_func();
foo1.c
void ext_func(){
....
}
foo2.c
#include "foo1.h"
int Modelica_func(){
ext_func();
}
I defined ext_func() in foo1.c. Then, in foo1.h I declared it to be extern, because I want to use it in foo2.c. Modelica_func() is the function that I will be using in Modelica.
The compiler always throws out error LNK2019 to me complaining unresolved external symbol, I guess it's probably due to the reason that the header file cannot find it's matching c file. I am working in Dymola, and I've put all of these files in WorkingFolder/Sources/Include. But still I got the same error. I want others to see my code, so I cannot use static or dynamic library.
Greatly appreciated if anyone could help me a bit of this. THANKS!

You can find some details in Section 12.9.4 of the Modelica Specification.

Related

Can't resolve C warning in STM32CubeIDE

Facing a a warning which I am not able to get rid of. I am using stm32 MCU and STM32CubeIDE with a standard C11 compiler. Array gpioOutPins is used by in a function call gpio.c file. This function which contains this function call is called from inOut.c file.
Please note that the inOut.c file is in User Application layer while the gpio.c file is in the Kernel (Core) section of the project tree as can be seen below. I was not able to accommodate the whole project tree in the snapshot.
I don't understand why this warning is generated.
Any help is appreciated. Thank you.
An array is deifned in a header file gpio.h:
static uint16_t gpioOutPins[GPIO_OUT_CH_NR] =
{
DOUT_OD_OUT4_Pin,
DOUT_OD_OUT6_Pin,
DOUT_OD_OUT5_Pin,
DOUT_OD_OUT7_Pin,
DOUT_LED_DISABLE_Pin,
DOUT_BUZZ_Pin,
DOUT_OD_OUT8_Pin,
DOUT_OD_OUT3_Pin,
DOUT_OD_OUT2_Pin,
DOUT_OD_OUT1_Pin,
DOUT_ALARM_Pin,
DOUT_12V_PWR_Pin,
DOUT_12V_PWR_Pin
};
The directory structure looks like this:
The warning generated by the compiler is this:
warning: 'gpioOutPins' defined but not used [-Wunused-variable]
Header (.h) files are not a good place to define global variables, because when they are included in source (.c) files, multiple independent copies of them come to existence. They share the same name, but they are actually different variables. And if they are not static, the linker rejects them because of multiple definitions.
Your inOutTask.c probably includes gpio.h header directly or indirectly, so another copy of gpioOutPins comes into existence, which is distinct from the one used in gpio.c. Because you don't use gpioOutPins in inOutTask.c, you get the warning.
The proper way is to move the definition into gpio.c, remove the static keyword, and add extern uint16_t gpioOutPins[GPIO_OUT_CH_NR]; to gpio.h

How do I fix collect2 error while compiling an old MUD?

I'm trying to run make on an Ubuntu machine to compile a RoT MUD, but the farthest I've gotten is when I get a collect2: error: ld returned 1 exit status.
This is what comes immediately before the error in the terminal (along with a lot of other similar errors):
/usr/bin/ld: obj/wizlist.o:/home/lucas/Projects/R2b5/src/merc.h:3355: multiple definition of `bllmax'; obj/act_comm.o:/home/lucas/Projects/R2b5/src/merc.h:3355: first defined here
From what I've gathered this means that the header files have variable declarations in them, and that using static is an easy fix, however, I haven't been able to figure out where I should put that keyword in the code to fix this issue. The following is the only mention of bllmax in merc.h:
int bllmax, crbmax, crnmax, srpmax, mngmax;
Here is the program I'm trying to compile.
You need to learn the difference between declaration and definition. A declaration is telling the compiler that the symbol exists somewhere but possibly not here. A definition is telling the compiler that the symbol exists here.
The line you show (without any context) is defining the variables, which means they will be defined in each source file that includes the header file.
What it should do is to declare the variables, which can be done by making them extern:
extern int bllmax, crbmax, crnmax, srpmax, mngmax;
Then in a single source file define the variables (without extern).

LNK2019 unresolved external symbol _GetExtendedTcpTable#24 [duplicate]

During coding in Visual Studio I got an unresolved external symbol error
and I've got no idea what to do. I don't know what's wrong.
Could you please decipher me? Where should I be looking for what kind of errors?
1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField#Field##QAEPAV1#PAV1##Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse#Form##QAEXAAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse#Field##UAEXAAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField##QAE#AAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt#Field##UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName#Field##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType#Field##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe#Field##UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals
This error often means that some function has a declaration, but not a definition.
Example:
// A.hpp
class A
{
public:
void myFunc(); // Function declaration
};
// A.cpp
// Function definition
void A::myFunc()
{
// do stuff
}
In your case, the definition cannot be found. The issue could be that you are including a header file, which brings in some function declarations, but you either:
do not define the functions in your cpp file (if you wrote this code yourself)
do not include the lib/dll file that contains the definitions
A common mistake is that you define a function as a standalone and forget the class selector, e.g. A::, in your .cpp file:
Wrong: void myFunc() { /* do stuff */ }
Right: void A::myFunc() { /* do stuff */ }
Check you are including all the source files within your solution that you are referencing.
If you are not including the source file (and thus the implementation) for the class Field in your project it won't be built and you will be unable to link during compilation.
Alternatively, perhaps you are using a static or dynamic library and have forgotten to tell the linker about the .libs?
It looks to be missing a library or include, you can try to figure out what class of your library that have getName, getType etc ... and put that in the header file or using #include.
Also if these happen to be from an external library, make sure you reference to them on your project file. For example, if this class belongs to an abc.lib then in your Visual Studio
Click on Project Properties.
Go to Configuration Properties, C/C++,
Generate, verify you point to the abc.lib location under Additional
Include Directories. Under Linker, Input, make sure you have the
abc.lib under Additional Dependencies.
I've just seen the problem I can't call a function from main in .cpp file, correctly declared in .h file and defined in .c file. Encountered a linker error. Meanwhile I can call function from usual .c file. Possibly it depends on call convention. Solution was to add following preproc lines in every .h file:
#ifdef __cplusplus
extern "C"
{
#endif
and these in the end
#ifdef __cplusplus
}
#endif
I had an error where my project was compiled as x64 project. and I've used a Library that was compiled as x86.
I've recompiled the library as x64 and it solved it.
sometimes if a new header file is added, and this error starts coming due to that, you need to add library as well to get rid of unresolved external symbol.
for example:
#include WtsApi32.h
will need:
#pragma comment(lib, "Wtsapi32.lib")
I had the same link errors, but from a test project which was referencing another dll. Found out that after adding _declspec(dllexport) in front of each function which was specified in the error message, the link was working well.
Yet another possible problem (that I just scratched my head about for some time):
If you define your functions as inline, they—of course!—have to be defined in the header (or an inline file), not a cpp.
In my case, they were in an inline file, but only because they were a platform specific implementation, and a cpp included this corresponding inl file… instead of a header. Yeah, s**t happens.
I thought I'd leave this here, too, maybe someone else runs into the same issue and finds it here.
This error can be caused by putting the function definitions for a template class in a separate .cpp file. For a template class, the member functions have to be declared in the header file. You can resolve the issue by defining the member functions inline or right after the class definition in the .h file.
For example, instead of putting the function definitions in a .cpp file like for other classes, you could define them inline like this:
template<typename T>
MyClassName {
void someFunction() {
// Do something
...
}
void anotherFunction() {
// Do something else
...
}
}
Or you could define them after the class definition but in the same file, like this:
template<typename T>
MyClassName {
void someFunction();
void anotherFunction();
}
void MyClassName::someFunction() {
// Do something
...
}
void MyClassName::anotherFunction() {
// Do something else
...
}
I just thought I'd share that since no one else seems to have mentioned template classes. This was the cause of the error in my case.
In addition to the excellent answer by Chris Morris above, I found a very interesting way you can receive this same fault if you are calling to a virtual method that hasn't been set to pure but doesn't its own implementation. It is the exact same reason (the compiler can't find an implementation of the method and therefore crooks), but my IDE did not catch this fault in the least bit.
for example, the following code would get a compilation error with the same error message:
//code testing an interface
class test
{
void myFunc();
}
//define an interface
class IamInterface
{
virtual void myFunc();
}
//implementation of the interface
class IamConcreteImpl
{
void myFunc()
{
1+1=2;
}
}
However, changing IamInterface myFunc() to be a pure virtual method (a method that "must" be implemented, that than a virtual method which is a method the "can" be overridden) will eliminate the compilation error.
//define an interface
class IamInterface
{
virtual void myFunc() = 0;
}
Hopes this helps the next StackOverFlow person stepping through code!
I believe most of the points regarding the causes and remedies have been covered by all contributors in this thread. I just want to point out for my 'unresolved external' problem, it was caused by a datatype defined as macro that gets substituted differently than expected, which results in that incorrect type being supplied to the function in question, and since the function with type is never defined, it couldn't have been resolved. In particular, under C/C++ -> Language, there is an attribute called 'Treat WChar_t As Built in Type, which should have been defined as 'No (/Zc:wchar_t-)' but did not in my case.
I just had a hard time with this. Everything was logically set up. I declared a constructor but didn't define it
class SomeClass
{
SomeClass(); // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}
I almost banged my head on my keyboard when I forgot something so elementary.
See Linker Tools Error LNK2019 at MSDN, it has a detailed list of common problems that cause LNK2019.
Make sure you decorate your header files with
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
// your header code here
#endif
Bad things -including this- can happen if you don't
I'm doing some C++ for the first time in a long time, and I'm getting this error when I forget to add the ClassName:: prefix for the function definition, since this is a little unique to C++. So remember to check for that too!
POINTERS
I had this problem and solved it by using pointer. I see that this wasn't your issue but I thought I'd mention it because I sure wish it had been here when I saw this an hour ago. My issue was about declaring a static member variable without defining it (the definition needed to come after some other set ups) and of course a pointer doesn't need a definition. Equally elementary mistake :P
One possible cause of this linker error can also be inline functions that are declared but not defined in a header file that is then included somewhere else. Inline functions have to be defined in every translation unit they are used in.
Make sure that you are not trying to overload the insertion or extraction operators as inline functions. I had this problem and it only went away when i removed that keyword.
What had caused it in my case:
I had a huge file Foo.cpp without a Foo.h. Foo.cpp began like this:
// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;
I removed the "static" keyword and added a Foo.h with this:
extern int var;
Do you see the mistake?
I totally missed that var was originally defined in a namespace, because the namespace declaration was buried in other code. The fix is to change the extern like this:
namespace NS {
extern int var;
}
In my case, I needed add the function name to the DEF file.
LIBRARY DEMO
EXPORTS
ExistingFunction #1
MyNewFunction #2
My issue was a sconscript did not have the cpp file defined in it. This can be very confusing because Visual Studio has the cpp file in the project but something else entirely is building.
My issue was: I had to do forward declaration of the class whose ctor was "unresolved external".
In the file where I got the error, I had to put something like this:
#include "ClassB"
class ClassB; // this solved the problem
class ClassA{
void foo(){
ClassB* tmp = new ClassB();
// ...
}
};
Of course, my project is much more complicated and this is just a snippet example. Also when using namespaces, declare them as well.
Just spent a couple of hours to find that the issue was my main file had extension .c instead of .cpp
:/
Yet another possibility to check, it was my problem this time.
I had added the function to the library, and included the library's output folder in the search path.
But I also had a folder with an older version of the library listed before, so VS was using the old library, and of course not finding the new function.
A possible reason for the "Unresolved external symbol" error can be the function calling convention.
Make sure that all the source files are using same standard (.c or .cpp), or specify the calling convention.
Otherwise, if one file is a C file (source.c) and another file is a .cpp file, and they link to the same header, then the "unresolved external symbol" error will be thrown, because the function is first defined as a C cdecl function, but then C++ file using the same header will look for a C++ function.
To avoid the "Unresolved external symbol error", make sure that the function calling convention is kept the same among the files using it.
I came here looking for a possible explanation before taking a closer look at the lines preceding the linker error. It turned out to have been an additional executable for which the global declaration was missing!
I faced a similar issue and finally managed to solve it by adding __declspec(dllimport) to the declaration of the class:
// A.hpp
class __declspec(dllimport) A
{
public: void myFunc();
// Function declaration
};
In my case I had multiple namespaces in my header file without nesting (one after the other) however in my source file I had accidentally nested one of the namespaces inside another:
// myExample.h
#ifndef MYEXAMPLE_H
#define MYEXAMPLE_H
namespace A
{
void aFunc();
}
namespace B
{
void bFunc();
}
// myExample.cpp
#include "myExample.h"
namespace A
{
void aFunc()
{
...
}
namespace B // whoops! I nested this inside namespace A when I didn't mean to.
{
void bFunc()
{
...
}
}
}
// main.cpp
#include "myExample.h"
int main()
{
myExample::B::bFunc();
return 0;
}
When I used F12 to "Go to definition" on the function in Main, Visual Studio found the code in the source file even though it was declared in a deeper namespace by accident.
Debugging Technique
I spotted the issue when renaming the function while trying to debug the issue. The rename preview window showed an "External References" node with the function inside the source file clearly nested under another namespace by accident.
I had the same issue. Mine was working one day and then not the next day after I pulled the latest code.
The latest code did not include the project I was referencing in my library. So when I rebuilt my library, it deleted that .obj file, whoopsy.....
I reincluded the project I needed, built my library, then rebuilt my project that was failing and it worked fine.
Moral of the story, verify your .obj file is where you are referencing it before diving too deep into the rabit hole.
I have had an issue with the same error within my project which I have managed to resolved.
The problem led me here but I found it to be a build file problem within visual studio itself.
If you cannot find anything wrong with your code and your doing all of the above I would recommend looking in the yourProject.vcxproj file and check that it is including your MyClass.cpp and source files as
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="myClass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
</ItemGroup>
SynthProject.vcxproj.filters
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
and not as
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
<ClInclude Include="myClass.cpp" />
</ItemGroup>
SynthProject.vcxproj.filters
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
I have managed to do this manually but would recommend unloading and adding the file back into the project if you do not have, or not using git.

Include c file in another

I want to include a .c file in another. Is it possible right? It works well if I include a header file in a .c file, but doesn't work as well if I include a .c file in another .c file.
I am using Visual Studio and I get the following error:
main.obj : error LNK2005: _sayHello already defined in sayHello.obj
/* main.c */
#include "sayHello.c"
int main()
{
return 0;
}
/* sayHello.c */
#include <stdio.h>
void sayHello()
{
printf("Hello World");
}
I don't know what this error could mean. Time to ask more advanced C coders. :)
I want to include a .c file in another.
No you don't. You really, really don't. Don't take any steps down this path; it only ends in pain and misery. This is bad practice even for trivial programs such as your example, much less for programs of any real complexity. A trivial, one-line change in one file will require you to rebuild both that file and anything that includes it, which is a waste of time. You lose the ability to control access to data and functions; everything in the included .c file is visible to the including file, even functions and file scope variables declared static. If you wind up including a .c file that includes another .c file that includes another .c file und so weiter, you could possibly wind up with a translation unit too large for the compiler to handle.
Separate compilation and linking is an unequivocal Good Thing. The only files you should include in your .c files are header files that describe an interface (type definitions, function prototype declarations, macro defintions, external declarations), not an implementation.
It works, but you need to be careful with how you build the program. Also, as folks have pointed out in comments, it's generally considered a bad idea. It's unexpected, and it creates problems like these. There are few benetfits, especially for what seems like a trivial program. You should probably re-think this approach, altogether.
After doing something like this, you should only compile main.c, and not attempt to link it with the result of compiling sayHello.c, which you seem to be doing.
You might need to tell Visual Studio to exclude the latter file from the build.
Yes, any '.c' file can be included into another program.
As one include '.h' file like 'stdio.h' in the program.
After that we can call those function written into this external file.
test.c::
#include<stdio.h>
#include<conio.h>
void xprint()
{
printf("Hello World!");
}
main.c::
#include "test.c"
void main()
{
xprint();
getch();
}
Output:: Hello World!
This is a linker error. After compiling all your .c files to .obj files (done by the compiler) the linker "merges" them together to make your dll/exe. The linker has found that two objects declare the same function (which is obviously not allowed). In this case you would want the linker to only process main.obj and not sayhello.obj as well (as its code is already included in main.obj).
This is because in main.obj you will ALSO have the sayHello() function due to the include!
sayHello.h
#include <stdio.h>
void sayHello(void);
main.c
#include "sayHello.h"
int main()
{
sayHello();
return 0;
}
You probably defined two times this function
void sayHello()
{
printf("Hello World");
}
one in your current file and one in sayhello.c
You must remove one definition.
The problem seems to be that sayHello.c got compiled into an object file called sayHello.obj, and main.c (also including all the source text from sayHello.c), got compiled into main.obj, and so both .obj files got a copy of all the external symbols (like non-static function definitions) from sayHello.c.
Then all the object files were supposed to get "linked" together to produce the final executable program file, but the linking breaks when any external symbols appear more than once.
If you find yourself in this situation, you need to stop linking sayHello.obj to main.obj (and then you might not want to compile sayHello.c by itself into its own object file at all).
If you manually control every step of the build (like you might when using the CLI of your compiler), this is often just a matter of excluding that object file from the invocation of the linker or compiler.
Since you are using Visual Studio, it's probably making a bunch of assumptions for you, like "every .c file should be compiled into its own object file, and all those object files should be linked together", and you have to find a way to circumvent or disable this assumption for sayHello.c.
One easy and somewhat idiomatic solution might be to rename sayHello.c into sayHello.c.inc.
//THIS IS THE MAIN FILE//
#include "test.c"
int main()
{
multi(10);
}
//THIS IS THE TEST FILE//
#include<stdio.h>
void multi(int a)
{
printf("%d",a*2);
}
POINTS TO BE NOTED:
Here you need to run the program which contains "main()" function.
You can avoid the "stdio.h" header file in main function. Because, you are including the file which already contains the "stdio.h" header file.
You have to call the function from the "main" file.
The including file should be "file_name.c" not "file_name.h". Because usually we use .h extension for the header file. Since we are including another program file and not the header file, we have to use .c. Otherwise it will give you Fatal Error and the Compilation gets terminated.

Typedefs included, but not functions

I'm writing some code that uses a C library provided by MATLAB (to extract data from *.mat files). In my IDE (Code::Blocks), I've included the folder containing the necessary "mat.h", which is on a network drive. My code recognises types defined in mat.h when I do this, but whenever I call functions from the file I get an "undefined reference" error. This is the same case for the example code MathWorks provides. What sort of problem usually causes this?
#include "mat.h"
int main (void) {
MATFile *pmat; // Compiles only when compiler is told to search in mat.h directory
pmat = matOpen("example_filename", "r"); // Never compiles
return 0;
}
Thanks!
Cameron
"undefined reference" is normally a linker error. It's not a problem of a header file. You need to tell the linker to link MATLAB's library (or a dedicated object) to your program.
No idea how this is done in Code::Blocks though. In the Code:Blocks documentation it is described here.
Have you checked the contents of mat.h? Does it declare matOpen()? Also, does the error occur when compiling or linking? If it's during the link phase, you probably need to reference the library that contains the implementation of matOpen() (a .lib in Windows, or .a in Unix). The .h file only declares the function.

Resources