When I build main.cpp get error: undefined reference to WinMain#16, use Code::Blocks created dll project in codeblocks
When I build main.cpp get error: undefined reference to WinMain#16, use Code::Blocks created dll project in codeblocks
When I build main.cpp get error: undefined reference to WinMain#16, use Code::Blocks created dll project in codeblocks
When I build main.cpp get error: undefined reference to WinMain#16, use Code::Blocks created dll project in codeblocks
main.cpp (created by code:blocks)
#include "main.h"
#include <string>
#include <fstream>
#include <windows.h>
#include <iostream>
#include <io.h>
using namespace::std;
void DLL_EXPORT createFiles(int filesAmount){
int n=5;
int a[5] = {1, 23, 47, 45, 21};
for(int i=0; i<filesAmount; i++){
string s1 = "files\\";
string s2 = to_string(i+1);
string s3 = s1 + s2 + ".txt";
ofstream fout(s3);
fout << "0";
fout.close();
}
for (int i=0; i<n; i++){
string s1 = "files\\";
string s2 = to_string(a[i]);
string s3 = s1 + s2 + ".txt";
ofstream fout (s3);
fout << "1";
fout.close();
}
}
DWORD WINAPI DLL_EXPORT lookForFile(void *data, HANDLE hSem){
Pair *pairs = (Pair *) data;
int start = (pairs->start);
int finish = (pairs->finish);
char a;
DWORD dwWaitResult = WaitForSingleObject( hSem, 1);
while(dwWaitResult!=WAIT_OBJECT_0)
{
cout << pairs->threadNumber << " thread waiting for semaphore..."
<<endl;
dwWaitResult = WaitForSingleObject( hSem, 1);
}
cout << pairs->threadNumber << " thread has been runned"<<endl;
Sleep(100);
for(int i=start; i<=finish; i++){
string s1 = "files\\";
string s2 = to_string(i+1);
string s3 = s1 + s2 + ".txt";
ifstream F(s3);
a = F.get();
if(a == '1')
cout << "\"1\" was found by " << (pairs->threadNumber) << " thread
in " << s2 <<".txt"<<endl;
F.close();
}
ReleaseSemaphore( hSem, 1, NULL );
cout << pairs->threadNumber << " thread has been finished"<<endl;
return 0;
}
void DLL_EXPORT makeCounts(int filesAmount, int numberOfThreads, Pair
pairs[]){
int fp = filesAmount/numberOfThreads-1;
int st = 0;
for(int i = 0; i < numberOfThreads; i++){
if(i == numberOfThreads-1){
pairs[i].start = st;
pairs[i].finish = filesAmount-1;
}
else{
pairs[i].start = st;
pairs[i].finish = st+fp;
st+=fp+1;
}
}
}
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD
fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}
main.h (created by code:blocks)
#ifndef __MAIN_H__
#define __MAIN_H__
struct Pair {
int start;
int finish;
int threadNumber;
};
#include <windows.h>
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
void DLL_EXPORT createFiles(int filesAmount);
DWORD WINAPI DLL_EXPORT lookForFile(void *data, HANDLE hSem);
void DLL_EXPORT makeCounts(int filesAmount, int numberOfThreads, Pair
pairs[]);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_H__
Related
I have two projects in my Solution (Visual Studio)
I want to assign the function
void _OnCycle()
{
printf("Success\n");
}
in the Dll( main.cpp ) to the pointer member function OnCycle of the structure PluginCallbacks.
extern "C" unsigned int PluginInit(PluginFuncs * pluginFuncs, PluginCallbacks * pluginCalls, PluginInfo * pluginInfo) {
pluginCalls->OnCycle = _OnCycle;
return 1;
}
But program is crashing. Entire code below.
//Project: ConsoleApplication1
//file: Dll1/ConsoleApplication1/ConsoleApplication1.cpp
#include <iostream>
#include "plugin.h"
#include <windows.h>
typedef unsigned int (__stdcall *PluginInit)(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo);
int main()
{
std::cout << "Loading first dll\n";
HINSTANCE hGetProcIDDLL = LoadLibrary("../Release/Dll1.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
// resolve function address here
PluginInit funci = (PluginInit)GetProcAddress(hGetProcIDDLL, "PluginInit");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
return EXIT_FAILURE;
}
PluginFuncs a;
PluginCallbacks b;
PluginInfo c;
std::cout << "PluginInit(a,b,c) returned " << funci(&a,&b, &c) << "\n";
std::cout << "Now going to call OnCycle\n";
b.OnCycle();
std::cout << "Done";
return EXIT_SUCCESS;
}
//Project: ConsoleApplication1
//file: Dll1/ConsoleApplication1/plugin.h
#pragma once
#include <stdint.h>
## Heading ##
typedef struct _Settings {
uint32_t structSize;
uint32_t flags;
} Settings;
typedef struct _PluginInfo {
uint32_t structSize;
char name[32];
} PluginInfo;
typedef struct _PluginFuncs {
uint32_t structSize;
uint32_t(*GetVersion) (void);
}PluginFuncs;
typedef struct {
uint32_t structSize;
void (*OnCycle) ();
}PluginCallbacks;
and second project
//Project: Dll1
//file: Dll1/Dll1/main.cpp
#include "plugin.h"
#include "main.h"
#include "stdio.h"
void _OnCycle() {
printf("Success\n");
}
extern "C" unsigned int PluginInit(PluginFuncs * pluginFuncs, PluginCallbacks * pluginCalls, PluginInfo * pluginInfo) {
printf("PluginInit called\n");
pluginCalls->OnCycle = _OnCycle;
return 1;
}
//Project: Dll1
//file: Dll1/Dll1/main.h
#define EXPORT __declspec(dllexport)
#include "plugin.h"
#ifdef __cplusplus
extern "C" {
#endif
EXPORT unsigned int PluginInit(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo);
#ifdef __cplusplus
}
#endif
//Project: Dll1
//file: Dll1/Dll1/plugin.h
#pragma once
#include <stdint.h>
typedef struct _Settings {
uint32_t structSize;
uint32_t flags;
} Settings;
typedef struct _PluginInfo {
uint32_t structSize;
char name[32];
} PluginInfo;
typedef struct _PluginFuncs {
uint32_t structSize;
uint32_t(*GetVersion) (void);
}PluginFuncs;
typedef struct {
uint32_t structSize;
void (*OnCycle) ();
}PluginCallbacks;
It builds but crashes on execution.
//Output
C:\Users\[hidden]\source\repos\Dll1\Release>ConsoleAPplication1
Loading first dll
PluginInit called
PluginInit(a,b,c) returned 1
Now going to call OnCycle
C:\Users\[hidden]\source\repos\Dll1\Release>
See, it crashes as 'Done' message not printed.
How this is to be done correctly.?
It seems my problem is solved by creating a pointer, malloc'ing it and passing it to dll.
Here is the piece of code
PluginFuncs* a = NULL;
PluginCallbacks* b = NULL;
PluginInfo* c = NULL;
a = (PluginFuncs*)malloc(sizeof(PluginFuncs));
b = (PluginCallbacks*)malloc(sizeof(PluginCallbacks));
c= (PluginInfo*)malloc(sizeof(PluginInfo));
std::cout << "PluginInit(a,b,c) returned " << funci(a,b, c) << "\n";
std::cout << "Now going to call OnCycle\n";
if (b && b->OnCycle)
b->OnCycle();
std::cout << "Done";
and output
Loading first dll
PluginInit(a,b,c) returned 1
Now going to call OnCycle
Success
Done
Thanks
I need to import the dll function into my project and use it.
However, when importing it into my project with GetProcAddress() function it does not seem to work. Function returns null and the simple if check finishes the program.
I'm pretty sure there is some problem with my code, but I don't seem to be able to find it. Here is the code of Library.h file
#pragma once
#include <iostream>
#include <windows.h>
#include <string>
#include <cmath>
using namespace std;
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API extern "C" _declspec(dllexport)
#else
#define MY_DLL_API extern "C" _declspec(dllimport)
#endif
struct args
{
int Elements;
int sum;
int* Array;
};
DWORD WINAPI NoSynchroSum(LPVOID);
void Monitoring(int);
Library.cpp file
#include "pch.h"
#include "framework.h"
#include "Library.h"
using namespace std;
DWORD WINAPI NoSynchroSum(LPVOID arg)
{
args* _args = (args*)arg;
for (int i = 0; i < _args->Elements; i++)
{
_args->sum += _args->Array[i];
}
return 0;
}
void Monitoring(int Elements)
{
int ElementsAmount = Elements;
HANDLE handle;
int suspendCount = 1;
int sum = 0;
srand(time(0));
int* Array = new int[ElementsAmount];
for (int i = 0; i < ElementsAmount; i++)
{
Array[i] = rand() % 21 - 10;
}
args* _args = new args;
_args->Elements = ElementsAmount;
_args->sum = sum;
_args->Array = Array;
handle = CreateThread(NULL, 0, NoSynchroSum, (LPVOID)_args, NULL, NULL);
cout << "Counted Sum = " << sum << endl;
CloseHandle(handle);
delete[] Array;
delete _args;
}
And my other project code, where i'm trying to import and use the function
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
HINSTANCE hInstance = LoadLibrary(L"D:\\Visual Studio 2022\\repos\\LabOS_7_DLL\\x64\\Debug\\DLLibrary.dll");
if (!hInstance) {
std::cout << "Library not loaded.\n";
return 1;
}
void (*pMainFunc)(int);
pMainFunc = (void(*)(int))GetProcAddress(hInstance, "Monitoring"); // експорт функції створення потоку
if (!pMainFunc)
{
std::cout << "Function not loaded.\n";
return 1;
}
int ElementsAmount = 0;
while (true)
{
cout << "enter size of array: ";
cin >> ElementsAmount;
if (ElementsAmount < 100)
{
cout << "size of array must be >=100\n";
continue;
}
break;
}
pMainFunc(ElementsAmount);
FreeLibrary(hInstance);
return 0;
}
I test the code and get the GetLastError:127 ERROR_PROC_NOT_FOUND:The specified procedure could not be found.
It means that there is no exported function with that name.
I suggest you should use the following code in the Library.h:
MY_DLL_API DWORD WINAPI NoSynchroSum(LPVOID);
MY_DLL_API void Monitoring(int);
I have a dll project (Server.dll) containing a Server.cpp
Server.cpp
#include "pch.h"
#include "Server.hpp"
extern "C" {
_declspec(dllexport) int Server::Add(int a, int b)
{
return a + b;
}
}
#define Function( Y ) \
\
extern "C" __declspec( dllexport)\
std::string Server::Y(std::string const& name) {\
return name; \
}\
I use these two functions in an other project client.exe
Here the main
#include <Windows.h>
#include <iostream>
typedef int(*pAdd) (int a, int b);
int main()
{
std::string path = "D:\\project\\Server.dll";
std::wstring stemp = std::wstring(path.begin(), path.end());
LPCWSTR sw = stemp.c_str();
HINSTANCE hinstance = LoadLibrary(sw);
if(!hinstance)
std::cout << "canot load library\n";
pAdd obj = (pAdd)GetProcAddress(hinstance, "Add");
if (obj) {
int result = obj(10, 20);
std::cout << "result = " << result << std::endl;
}
std::string func = "Client";
std::cout << "address = " << GetProcAddress(hinstance, "Y");
}
i can load Add function but i can't load Y function (address = 0000000000)
Any suggestions please ?
I want to post an example of the solution here maybe someone needs one day to create a macro function containing a function:
I have a dll project containing a class:
Here the code
#include "pch.h"
#include <iostream>
#define Function( Y ) \
\
extern "C" __declspec( dllexport)\
int Y(int a, int b) {\
return (a+b); \
}\
class TestMacro {
Function(Add);
};
In another exe project i loaded this function and use it here the code:
#include <Windows.h>
#include <iostream>
typedef int(*Y)(int a, int b);
int main()
{
std::string path = "D:\\project\\Server.dll";
std::wstring stemp = std::wstring(path.begin(), path.end());
LPCWSTR sw = stemp.c_str();
HINSTANCE hinstance = LoadLibrary(sw);
if(!hinstance)
std::cout << "canot load library\n";
std::cout << "address = " << GetProcAddress(hinstance, "Add")<< std::endl;
Y y = (Y)GetProcAddress(hinstance, "Add");
int result = y(2,3);
std::cout << "appel Y = " << result<< std::endl;
}
Here the ouput
address = 00007FFBF98C132F
appel Y = 5
I've started working with libmemleak library and I tried getting the basic sample code to work.
I'm able to catch leaks but when trying to view the backtraces i get cryptic messages.
Using the hello.cc example for libmemleak, on one terminal running:
LD_PRELOAD='/usr/local/lib/libmemleak.so /usr/lib/x86_64-linux-gnu/libdl.so /usr/lib/x86_64-linux-gnu/libbfd.so' ./hello
On another terminal running:
./memleak_control
then
libmemleak>start
and
libmemleak>dump 49
Leaking sample code (hello.cc example from libmemleak repository):
#include <iostream>
#include <cstdlib>
#include <inttypes.h>
#include <deque>
#include <cstdio>
extern "C" {
#include "addr2line.h"
}
#ifdef DIRECT_LINKED
extern "C" void memleak_stats();
extern "C" void interval_restart_recording(void);
extern "C" void interval_stop_recording(void);
#endif
void do_work(bool leak);
void* thread_entry0(void*) { do_work(false); return NULL; }
void* thread_entry1(void*) { do_work(true); return NULL; }
void* thread_entry2(void*) { do_work(false); return NULL; }
void* thread_entry3(void*) { do_work(false); return NULL; }
void purge(void);
#ifdef DIRECT_LINKED
void* monitor(void*);
int quit = 0;
#endif
size_t leaked_mem = 0;
int main()
{
std::cout << "Entering main()" << std::endl;
#ifdef DIRECT_LINKED
memleak_stats();
#endif
int const threads = 4;
pthread_t thread[threads];
for (int i = 0; i < threads; ++i)
{
switch(i)
{
case 0:
pthread_create(&thread[0], NULL, &thread_entry0, NULL);
break;
case 1:
pthread_create(&thread[1], NULL, &thread_entry1, NULL);
break;
case 2:
pthread_create(&thread[2], NULL, &thread_entry2, NULL);
break;
case 3:
pthread_create(&thread[3], NULL, &thread_entry3, NULL);
break;
}
}
#ifdef DIRECT_LINKED
pthread_t monitor_thread;
pthread_create(&monitor_thread, NULL, &monitor, NULL);
#endif
for (int i = 0; i < threads; ++i)
pthread_join(thread[i], NULL);
std::cout << "All threads exited. Purging and terminating monitor thread." << std::endl;
purge();
#ifdef DIRECT_LINKED
quit = 1;
pthread_join(monitor_thread, NULL);
interval_stop_recording();
#endif
std::cout << "Deliberate number of missed calls to free(): " << leaked_mem << std::endl;
#ifdef DIRECT_LINKED
memleak_stats();
#endif
}
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
std::deque<void*> allocations;
void store(void* ptr)
{
if (!ptr)
return;
pthread_mutex_lock(&mutex);
allocations.push_back(ptr);
pthread_mutex_unlock(&mutex);
}
void* remove(void)
{
void* ret = NULL;
pthread_mutex_lock(&mutex);
if (!allocations.empty())
{
ret = allocations.front();
allocations.pop_front();
}
pthread_mutex_unlock(&mutex);
return ret;
}
void purge(void)
{
int count = 0;
pthread_mutex_lock(&mutex);
while (!allocations.empty())
{
free(allocations.front());
allocations.pop_front();
++count;
}
pthread_mutex_unlock(&mutex);
std::cout << "Purged " << count << " allocations." << std::endl;
}
void do_work(bool leak)
{
struct random_data rdata;
int32_t rvalue;
char rstatebuf[256];
initstate_r(0x1234aabc, rstatebuf, sizeof(rstatebuf), &rdata);
for (int i = 0; i < 1000000000; ++i)
{
random_r(&rdata, &rvalue);
rvalue >>= 8;
bool allocate = rvalue & 1;
int how = (rvalue >> 1) & 0x3;
size_t size = (rvalue >> 3) & 0xff;
bool leak_memory = leak && ((rvalue >> 19) & 0xfff) == 0;
if (!allocate)
{
void* ptr = remove();
if (!leak_memory)
{
free(ptr);
}
else if (ptr)
++leaked_mem;
}
else
{
if (how == 0)
store(realloc(remove(), size));
else if (how == 1)
store(calloc(13, size / 13));
else
store(malloc(size));
}
}
pthread_exit(0);
}
Actual:
libmemleak> dump 49
#0 00007f383ffa9d76 in malloc at /home/rfogel/workspace/libmemleak/src/memleak.c:1008
#1 00005587313eaa1a in "hello"
#2 00005587313eaa9e in "hello"
#3 00007f383efa64a4 in start_thread at /build/glibc-77giwP/glibc-2.24/nptl/pthread_create.c:456
#4 00007f383ece8d0f in ?? at /build/glibc-77giwP/glibc-2.24/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:99
Expected:
libmemleak> dump 49
#0 00007f84b862d33b in malloc at /home/carlo/projects/libmemleak/libmemleak-objdir/src/../../libmemleak/src/memleak.c:1008
#1 00000000004014da in do_work(int)
#2 000000000040101c in thread_entry0(void*)
#3 00007f84b7e7070a in start_thread
#4 00007f84b7b9f82d in ?? at /build/glibc-Qz8a69/glibc-2.23/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:99
I've reached out to the main developer for libmemleak and he fixed the relevant code in addr2line.c file inside the library code.
Link to the commit:
https://github.com/CarloWood/libmemleak/commit/ec1080cef9b33515c4e2472f1418c5bb75af1d96
It works perfectly now.
This is my second attempt at a C++ program so I'm still learning.
I'm trying to create a DLL to work with Metatrader 4 which uses the ta-lib technical analysis library using Visual Studio 2013 Community.
However, when I build the solution I get the following linker errors and I don't know how to fix them.
Error 4 error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info##AAE#ABV0##Z) already defined in libcmt.lib(typinfo.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(ti_inst.obj) iDEMA
Error 5 error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info##AAEAAV0#ABV0##Z) already defined in libcmt.lib(typinfo.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(ti_inst.obj) iDEMA
Error 2 error LNK2005: _free already defined in libcmt.lib(free.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(MSVCR120.dll) iDEMA
Error 3 error LNK2005: _malloc already defined in libcmt.lib(malloc.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(MSVCR120.dll) iDEMA
Warning 1 warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\LINK iDEMA
Error 7 error LNK1169: one or more multiply defined symbols found C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\Release\iDEMA.dll iDEMA
Error 6 error LNK2005: _DllMain#12 already defined in uafxcw.lib(dllmodul.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\* CIL library *(* CIL module *) iDEMA
My header file is this
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the IDEMA_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// IDEMA_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef IDEMA_EXPORTS
#define IDEMA_API __declspec(dllexport)
#else
#define IDEMA_API __declspec(dllimport)
#endif
#pragma pack(push,1)
struct RateInfo
{
__int64 ctm;
double open;
double low;
double high;
double close;
unsigned __int64 vol_tick;
int spread;
unsigned __int64 vol_real;
};
#pragma pack(pop)
enum ENUM_PRICE
{
PRICE_OPEN,
PRICE_LOW,
PRICE_HIGH,
PRICE_CLOSE
};
// This class is exported from the iDEMA.dll
class IDEMA_API CiDEMA {
public:
CiDEMA(void);
double iDEMA(RateInfo, int, int, int, ENUM_PRICE);
};
extern IDEMA_API int niDEMA;
IDEMA_API int fniDEMA(void);
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include "C:\ta-lib-0.4.0-msvc\ta-lib\c\include\ta_libc.h"
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
And my code is this
// iDEMA.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "iDEMA.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define WIN32_LEAN_AND_MEAN
#define MT4_EXPFUNC __declspec(dllexport)
using namespace std;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
//---
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
//---
return(TRUE);
}
MT4_EXPFUNC double __stdcall iDEMA(const RateInfo* rates, const int rates_total, const int period, const int shift, const ENUM_PRICE applied_price)
{
//---
if (rates == NULL)
{
printf("iDEMA: NULL array\n");
return(0.0);
}
//---
if (rates_total<0 || rates_total<2 * period)
{
printf("iDEMA: wrong rates_total number (%d)\n", rates_total);
return(0.0);
}
//---
if (period<2 || period>100000)
{
printf("iDEMA: wrong period number (%d)\n", period);
return(0.0);
}
//---
if (shift<0 || shift >= rates_total)
{
printf("iDEMA: wrong shift number (%d)\n", shift);
return(0.0);
}
//---
if (applied_price<0 || applied_price>3)
{
printf("iDEMA: wrong applied price (%d)\n", applied_price);
return(0.0);
}
//---
TA_RetCode retCode;
retCode = TA_Initialize();
if (retCode != TA_SUCCESS)
{
printf("TA_LIB initialistion failed (%d)!\n", retCode);
return(0.0);
}
vector<TA_Real> dataArray;
const TA_Real* dataArray_c_pointer = dataArray.data();
// DEMA = ( 2 * EMA(n)) - (EMA(EMA(n)) ), where n= period
for (int nitem = rates_total - 1 - shift - (2 * period); nitem < rates_total - 1 - shift; nitem++)
{
TA_Real value = 0.0;
switch (applied_price)
{
case PRICE_OPEN: value = rates[nitem].open; break;
case PRICE_LOW: value = rates[nitem].low; break;
case PRICE_HIGH: value = rates[nitem].high; break;
case PRICE_CLOSE: value = rates[nitem].close; break;
}
dataArray[nitem] = value;
}
TA_Integer outBegin = 0, outElements = 0;
int beginIndx, endIndx;
beginIndx = endIndx = dataArray.size() - 1;
int array_size = endIndx - beginIndx + 1;
cout << "beginIndx = " << to_string(beginIndx) << endl << "endIndx = " << to_string(endIndx) << endl << "array_size = " << to_string(array_size) << endl;
vector<TA_Real> outDema(array_size, 0.0);
TA_Real* outDema_c_pointer = outDema.data();
retCode = TA_DEMA(beginIndx, endIndx, dataArray_c_pointer, period, &outBegin, &outElements, outDema_c_pointer);
double value = 0.0;
if (retCode == TA_SUCCESS)
{
cout << "outBegin = " << outBegin << " outElements = " << outElements << endl;
int lastElement = outElements - 1;;
cout << "outDema.at(" << to_string(lastElement) << ") = " << to_string(outDema.at(lastElement)) << endl;
delete dataArray_c_pointer;
delete outDema_c_pointer;
value = outDema.at(lastElement);
}
retCode = TA_Shutdown();
return value;
}
I installed the library using nuGet.
Could you help to compile this DLL please.
Thanks in advance.
Update 10/10/15
I removed the package nuGet and used static linking from a different directory.
I'm now getting these linker errors:
Error 2 error LNK1169: one or more multiply defined symbols found C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\Release\iDEMA.dll iDEMA
Error 1 error LNK2005: _DllMain#12 already defined in mfcs120u.lib(dllmodul.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\* CIL library *(* CIL module *) iDEMA
Still don't understand how to fix them!
Any help will be appreciated.
Thanks.
Try wrapping your header like this:
extern "C"
{
#include "stdafx.h"
#include "iDEMA.h"
}
If VS complains about the extern keyword go to Project Properties > C/C++ > Advanced > Compile As and check Compile as C++.
For the Updated answer, it looks like your compiler is seeing two definitions of the same symbol.
Try using
#include <stdafx.h>
#include <iDEMA.h>
They look in different places. If it doesn't help, try the extern "C" with your old project (before update 10/10/15).
Maybe you've added some dll or lib to your PATH in your first try and after the "Update 10/10/15", you don't need them anymore.
Also read this
answer
and this
MSDN Building Visual C++ page.
Edit:
If possible, create a new project. Maybe, in your attempts, you've messed something.
Managed to get it to link after modifying the header and source files. Here's the final result:
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the IDEMA_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// IDEMA_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#define WIN32_LEAN_AND_MEAN
#define MT4_EXPFUNC __declspec(dllexport)
#pragma pack(push,1)
struct RateInfo
{
__int64 ctm;
double open;
double low;
double high;
double close;
unsigned __int64 vol_tick;
int spread;
unsigned __int64 vol_real;
};
enum ENUM_PRICE
{
PRICE_OPEN,
PRICE_LOW,
PRICE_HIGH,
PRICE_CLOSE
};
#pragma pack(pop)
// This class is exported from the iDEMA.dll
class MT4_EXPFUNC CiDEMA {
public:
CiDEMA(void);
double iDEMA(RateInfo, int, int, int, ENUM_PRICE);
};
extern MT4_EXPFUNC int niDEMA;
MT4_EXPFUNC int fniDEMA(void);
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include "C:\ta-lib-0.4.0-msvc\ta-lib\c\include\ta_libc.h"
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
And the source file:
// iDEMA.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "iDEMA.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
MT4_EXPFUNC double __stdcall iDEMA(const RateInfo* rates, const int rates_total, const int period, const int shift, const ENUM_PRICE applied_price)
{
//---
if (rates == NULL)
{
printf("iDEMA: NULL array\n");
return(0.0);
}
//---
if (rates_total<0 || rates_total<2 * period)
{
printf("iDEMA: wrong rates_total number (%d)\n", rates_total);
return(0.0);
}
//---
if (period<2 || period>100000)
{
printf("iDEMA: wrong period number (%d)\n", period);
return(0.0);
}
//---
if (shift<0 || shift >= rates_total)
{
printf("iDEMA: wrong shift number (%d)\n", shift);
return(0.0);
}
//---
if (applied_price<0 || applied_price>3)
{
printf("iDEMA: wrong applied price (%d)\n", applied_price);
return(0.0);
}
//---
TA_RetCode retCode;
retCode = TA_Initialize();
if (retCode != TA_SUCCESS)
{
printf("TA_LIB initialistion failed (%d)!\n", retCode);
return(0.0);
}
vector<TA_Real> dataArray;
const TA_Real* dataArray_c_pointer = dataArray.data();
// DEMA = ( 2 * EMA(n)) - (EMA(EMA(n)) ), where n= period
for (int nitem = rates_total - 1 - shift - (2 * period); nitem < rates_total - 1 - shift; nitem++)
{
TA_Real value = 0.0;
switch (applied_price)
{
case PRICE_OPEN: value = rates[nitem].open; break;
case PRICE_LOW: value = rates[nitem].low; break;
case PRICE_HIGH: value = rates[nitem].high; break;
case PRICE_CLOSE: value = rates[nitem].close; break;
}
dataArray[nitem] = value;
}
TA_Integer outBegin = 0, outElements = 0;
int beginIndx, endIndx;
beginIndx = endIndx = dataArray.size() - 1;
int array_size = endIndx - beginIndx + 1;
cout << "beginIndx = " << to_string(beginIndx) << endl << "endIndx = " << to_string(endIndx) << endl << "array_size = " << to_string(array_size) << endl;
vector<TA_Real> outDema(array_size, 0.0);
TA_Real* outDema_c_pointer = outDema.data();
retCode = TA_DEMA(beginIndx, endIndx, dataArray_c_pointer, period, &outBegin, &outElements, outDema_c_pointer);
double value = 0.0;
if (retCode == TA_SUCCESS)
{
cout << "outBegin = " << outBegin << " outElements = " << outElements << endl;
int lastElement = outElements - 1;;
cout << "outDema.at(" << to_string(lastElement) << ") = " << to_string(outDema.at(lastElement)) << endl;
delete dataArray_c_pointer;
delete outDema_c_pointer;
value = outDema.at(lastElement);
}
retCode = TA_Shutdown();
return value;
}