I am dealing with a dll project for my internship. I have to write a C++ code including some basic functions for pl/sql with dev c compiler and it must be work as a pl/sql tool.I wrote this codes.And i save the source file as dll file.I copied the dll extension file to plugin directory of pl/sql developer.It did not work.
Thank you all.
Here is my header and source code.
// header file plsqlHx.h
#ifndef _DLL_H_
#define _DLL_H_
#define DLL_EX
#include <string>
using namespace std;
extern "C" __declspec (dllexport) DLL_EX const char* IdentifyPlugIn(int);
extern "C" __declspec (dllexport) DLL_EX const char* CreateMenuItem(int);
extern "C" __declspec(dllexport) DLL_EX void OnMenuClick(int);
#endif
#include "plsqlHx.h"
#include <iostream>
#include <windows.h>
#include <string>
const char *const Desc = "C++Builder Plug-In demo 1";
int PlugInID;
const char* IdentifyPlugIn(int ID){
PlugInID = ID;
return Desc;
}
const char* CreateMenuItem(int Index){
switch (Index)
{
case 1 : return "Tools / &Plug-In 1 Demo...";
}
return "";
}
void OnMenuClick (int Index){
switch(Index){
case 11:
cout << "Hello";
break;
case 12:
cout << "Goodbye";
break;
}
}
Related
I know it's not very good, but I need global variables across multiple files in my program. These are my graphics window's variables:
Name
Size
Status
.
I know I can make a .h file and declare all variables:
#pragma once
extern std::string GameName;
extern sf::RenderWindow Window;
extern std::string Status;
.
Then I want to define my variables in my main.cpp, so all files can access these values. But I cannot define these unless they are in the int main() loop. Is there another way, so I can define these variables not in main loop?
EDIT
Using Visual Studio 2017.
Errors:
LNK2001 unresolved external symbol "class sf::RenderWindow Window"
(?Window##3VRenderWindow#sf##A) Cubes
Library C:\Users\George\Documents\C++\Files\Libraries\Cubes
Library\Cubes Library\Cubes Library.obj 1
.
LNK2001 unresolved external symbol "class
std::basic_string,class
std::allocator > Status"
(?Status##3V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A) Cubes
Library C:\Users\George\Documents\C++\Files\Libraries\Cubes
Library\Cubes Library\Cubes Library.obj 1
.
LNK1120 2 unresolved externals Cubes
Library C:\Users\George\Documents\C++\Files\Libraries\Cubes
Library\Debug\Cubes Library.dll 1
You can declare them in your main.cpp file, but in order to make them globally accessible, you have to define them outside your main function/loop. If you decalre them inside your main function/loop, they are local variables and cannot (easily) be accessed globally. Doing it this way combined with the header file you suggested will work.
// Global variables...
std::string GameName;
sf::RenderWindow Window;
std::string Status;
int main()
{
return 0;
}
You could also put them in another file, for example globals.cpp.
You would do it like this...
File: Main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include <string>
extern std::string GameName;
//extern sf::RenderWindow Window;
extern std::string Status;
#endif
File: Main.cpp
#include "stdafx.h"
#include <iostream>
#include "Main.h"
std::string GameName;
//sf::RenderWindow Window;
std::string Status;
extern void foo(); // Function Prototype
int main()
{
GameName = "none";
Status = "none";
foo();
std::cout << GameName << " - " << Status << std::endl;
std::cout << "(HIT A KEY TO CONTINUE)" << std::endl;
getchar();
return 0;
}
File: Other.cpp
#include "stdafx.h"
#include "Main.h"
void foo()
{
// Global variables declared in Main.cpp are now accessible here
GameName = "Horizon New Dawn";
Status = "Finished";
}
This is how to do it using globals in a DLL.
// File: DLLGlobals.h
// This file is used in the DLL project
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
#include <string>
extern "C"
{
extern __declspec(dllexport) std::string GameName;
extern __declspec(dllexport) std::string Status;
}
#endif//__GLOBALS_H__
// File: DLLGlobals.cpp
#include "stdafx.h"
#include "DLLGlobals.h"
extern "C"
{
// Define Global Variables (no C++ mangling)
__declspec(dllexport) std::string GameName = "Dishonored 2";
__declspec(dllexport) std::string Status = "Not Started";
}
// File: DLL.h
#ifndef __DLL_H__
#define __DLL_H__
// This file is included by code using the DLL project
#include <string>
extern "C"
{
__declspec(dllimport) std::string GameName;
__declspec(dllimport) std::string Status;
}
#endif//__DLL_H__
// File: Main.cpp
#include "stdafx.h"
#include <iostream>
#include "Main.h"
#include "<path_to_dll_header>\DLL.h"
int main()
{
std::cout << GameName << ": " << Status << std::endl;
std::cout << "(HIT A KEY TO CONTINUE)" << std::endl;
getchar();
return 0;
}
I've some C++ APIs like below:
API1(std::string str, std::vector<std::string> vecofstr);
I want to call this API from a C code. How can i provide a C wrapper for this ?
std::string str
=>
I can probably use char* for std::string
&
std::vector<std::string> vecofstr =>
array of char* for vector of string like
char* arrOfstrings[SIZE];
This is what the corresponding C header (and its C++ implementation) could look like:
Declaration
#ifdef __cplusplus
extern "C"
#endif
void cAPI1(const char *str, const char * const *vecofstr, size_t vecofstrSize);
Implementation
extern "C" void cAPI1(const char *str, const char * const *vecofstr, size_t vecofstrSize)
{
API1(str, {vecofstr, vecofstr + vecofstrSize});
}
[Live example]
The above assumes that the C code will use zero-terminated strings for all string arguments. If that is not the case, the parameters of cAPI1 must be modified accordingly (ideally based on what representation of strings is actually used by the C code).
1.api.h
#ifndef API_H_
#define API_H_
#include <vector>
#include <string>
void api1(std::string& str, std::vector<std::string>& vecofstr);
#endif
.2. api.cpp
#include "api.h"
#include <iostream>
void api1(std::string& str, std::vector<std::string>& vecofstr) {
std::cout << str << std::endl;
for (size_t i=0; i<vecofstr.size(); i++) {
std::cout << vecofstr[i] << std::endl;
}
}
3.wrapper.h
#ifndef WRAPPER_H_
#define WRAPPER_H_
#define SIZE 2
#ifdef __cplusplus
extern "C" {
#endif
extern void wrapper1(char* p, char* [SIZE]);
#ifdef __cplusplus
};
#endif
#endif
4.wrapper.cpp
#include <string>
#include "wrapper.h"
#include "api.h"
#ifdef __cplusplus
extern "C" {
#endif
void wrapper1(char* p, char* ps[SIZE]) {
std::string str(p);
std::vector<std::string> vecofstr;
for (size_t idx=0; idx<SIZE; idx++) {
vecofstr.push_back(ps[idx]);
}
api1(str, vecofstr);
}
#ifdef __cplusplus
};
#endif
.5. test.c
#include "wrapper.h"
int main(void)
{
char* p = "hello world";
char* ps[] = {"world", "hello"};
wrapper1(p, ps);
return 0;
}
.6. compile
gcc -c api.cpp wrapper.cpp
gcc test.c -o test wrapper.o api.o -lstdc++
.7. run
./test
hello world
world
hello
I have a header file and its cpp file (Error.h, Error.cpp). The cpp file performs a check on a preprocessor directive but it always fails.
Error.h:
/*
Optional macros:
AE_EXIT_AT_ERROR
AE_CONSOLE_WRITE_AT_ERROR
*/
#pragma once
extern void aeError(const char *str, int code=1);
extern void aeAssert(bool b, const char *failStr = "assertion failed");
Error.cpp:
#include "Error.h"
#include <stdexcept>
#ifdef AE_CONSOLE_WRITE_AT_ERROR
#include <iostream>
#endif
void aeError(const char *str, int code)
{
#ifdef AE_CONSOLE_WRITE_AT_ERROR
std::cout << str << std::endl;
#endif
throw std::runtime_error(str);
#ifdef AE_EXIT_AT_ERROR
std::exit(code);
#endif
}
void aeAssert(bool b, const char *failStr)
{
if(!b)
aeError(failStr);
}
main.cpp:
//define both macros:
#define AE_CONSOLE_WRITE_AT_ERROR
#define AE_EXIT_AT_ERROR
#include "Error.h"
//rest of code
//...
both std::cout << str << std::endl; and std::exit(code); don't get compiled (I checked it "manually", although they are also marked gray by the IDE, which is VS2010).
What might be the cause of this?
main.cpp and Error.cpp are different translation units. You define the macro only for main.cpp, not for Error.cpp.
You should either put your #define directives in a header file included by both .cpp files, or define these macros in project settings/makefile.
//main.cpp
#include <iostream>
#include "worldActions.h"
using namespace std;
bool worldEvents = false;
void worldReactions(bool world);
int main (int argc, const char * argv[])
{
while (true)
{
if (worldAction == true)
{
worldEvents = true;
worldReactions(worldEvents);
}
else
{
worldEvents = false;
break;
}
}
return 0;
}
//1.cpp
#include <iostream>
#include "worldActions.h"
using namespace std;
bool worldAction;
//header
#ifndef worldActions_h
#define worldActions_h
bool worldAction = true;
#endif /* defined(__asdf_Story__worldActions__) */
When ever extern is used I get linking errors and when it's not I get redefinition errors. How can I fix this so I can use a global boolean?
You use extern bool worldAction; in the header and put the definition in the cpp file.
You are currently compiling a global worldAction into each file which includes your header. If more than one file includes the header or (as in your source file) any other file defines a variable with the same name, you'll get linker errors.
To fix this, change your header to declare the variable only
#ifndef worldActions_h
#define worldActions_h
extern bool worldAction;
#endif /* defined(__Julian_Story__worldActions__) */
and define/initialise it in your source file
#include <iostream>
#include "worldActions.h"
using namespace std;
bool worldAction = true;
use keyword externlike extern bool worldAction; & put definition bool worldAction = true in .cpp file
I've defined the following header file (in C), left out the function implementation since thise aren't needed:
#ifndef FFMPEG_MEDIAMETADATARETRIEVER_H_
#define FFMPEG_MEDIAMETADATARETRIEVER_H_
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int setDataSource(AVFormatContext** pFormatCtx, const char* path);
#endif /*FFMPEG_MEDIAMETADATARETRIEVER_H_*/
In C++, I defined my second header file:
#ifndef MEDIAMETADATARETRIEVER_H
#define MEDIAMETADATARETRIEVER_H
using namespace std;
extern "C" {
#include "ffmpeg_mediametadataretriever.h"
}
class MediaMetadataRetriever
{
public:
MediaMetadataRetriever();
~MediaMetadataRetriever();
int setDataSource(const char* dataSourceUrl);
};
#endif // MEDIAMETADATARETRIEVER_H
In, mediametadataretriever.cpp I defined the following function:
int MediaMetadataRetriever::setDataSource(
const char *srcUrl)
{
// should call C function
AVFormatContext* pFormatCtx;
return setDataSource(&pFormatCtx, srcUrl);
}
When I try to compile this (C++) project in Eclipse I get a "No matching function call..." error related to:
return setDataSource(&pFormatCtx, srcUrl);
If I comment out the call, the code compiles fine:
int MediaMetadataRetriever::setDataSource(
const char *srcUrl)
{
return 0;
}
This appears to be a linking issue, does anyone know what I'm doing wrong?
setDataSource in that context is the name of the member function. To invoke the free function, try fully qualifying its name:
return ::setDataSource(&pFormatCtx, srcUrl);
// ^^