panJames
asked on
Console program in C to DLL
Hello experts,
This is my second approach to this question.
I use VC++ 2008 Pro.
I have a program from the book. It compiles fine and creates console application.
Please have a look at the attachement.
I would like to make a dll from it to be able to use it in other applications.
I am trying to use an example of how to make dll files:
So I have three files.
***1***
DLL_Tutorial.h
#ifndef MY_HEADER
#define MY_HEADER
#define DECLDIR __declspec(dllexport)
extern "C"
{
DECLDIR int Add( int a, int b );
DECLDIR void Function( void );
}
#endif
***2***
def.def
LIBRARY dll_tutorial
DESCRIPTION "our simple DLL"
EXPORTS
Add @1
Function @2
***3***
DLL_Tutorial.cpp
#include <iostream>
#define DLL_EXPORT
#include "dll_tutorial.h"
{
DECLDIR int Add( int a, int b ) {
return( a + b );
}
DECLDIR void Function( void )
{
std::cout << "DLL Called!" << std::endl;
}
}
This dll compiles fine and works.
Now I try to make a really useful dll.
I add attached file to "Source Files", trying to compile it and I get lots of errors like:
ch8_ex8_3.obj : error LNK2019: unresolved external symbol _cvReleaseImage
referenced in function "int __cdecl main2(int,char * * const)"
(?main2@@YAHHQAPAD@Z)
ch8_ex8_3.obj : error LNK2019: unresolved external symbol _cvDestroyWindow
referenced in function "int __cdecl main2(int,char * * const)"
(?main2@@YAHHQAPAD@Z)
ch8_ex8_3.obj : error LNK2019: unresolved external symbol _cvWaitKey
referenced in function "int __cdecl main2(int,char * * const)"
(?main2@@YAHHQAPAD@Z)
Question:
How can I do it?
thank you
panJames ch8-ex8-3.cpp ch8-ex8-3.cpp
This is my second approach to this question.
I use VC++ 2008 Pro.
I have a program from the book. It compiles fine and creates console application.
Please have a look at the attachement.
I would like to make a dll from it to be able to use it in other applications.
I am trying to use an example of how to make dll files:
So I have three files.
***1***
DLL_Tutorial.h
#ifndef MY_HEADER
#define MY_HEADER
#define DECLDIR __declspec(dllexport)
extern "C"
{
DECLDIR int Add( int a, int b );
DECLDIR void Function( void );
}
#endif
***2***
def.def
LIBRARY dll_tutorial
DESCRIPTION "our simple DLL"
EXPORTS
Add @1
Function @2
***3***
DLL_Tutorial.cpp
#include <iostream>
#define DLL_EXPORT
#include "dll_tutorial.h"
{
DECLDIR int Add( int a, int b ) {
return( a + b );
}
DECLDIR void Function( void )
{
std::cout << "DLL Called!" << std::endl;
}
}
This dll compiles fine and works.
Now I try to make a really useful dll.
I add attached file to "Source Files", trying to compile it and I get lots of errors like:
ch8_ex8_3.obj : error LNK2019: unresolved external symbol _cvReleaseImage
referenced in function "int __cdecl main2(int,char * * const)"
(?main2@@YAHHQAPAD@Z)
ch8_ex8_3.obj : error LNK2019: unresolved external symbol _cvDestroyWindow
referenced in function "int __cdecl main2(int,char * * const)"
(?main2@@YAHHQAPAD@Z)
ch8_ex8_3.obj : error LNK2019: unresolved external symbol _cvWaitKey
referenced in function "int __cdecl main2(int,char * * const)"
(?main2@@YAHHQAPAD@Z)
Question:
How can I do it?
thank you
panJames ch8-ex8-3.cpp ch8-ex8-3.cpp
// Example 8-3. Finding and drawing contours on an input image
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
//Some defines we left out of the book
#define CVX_RED CV_RGB(0xff,0x00,0x00)
#define CVX_GREEN CV_RGB(0x00,0xff,0x00)
#define CVX_BLUE CV_RGB(0x00,0x00,0xff)
int main(int argc, char* argv[]) {
cvNamedWindow( argv[0], 1 );
IplImage* img_8uc1 = NULL;
//Changed this a little for safer image loading and help if not
if( argc != 2 || !(img_8uc1 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE )) ){
printf("\nExample 8_3 Drawing Contours\nCall is:\n./ch8_ex8_3 image\n\n");
return -1;}
IplImage* img_edge = cvCreateImage( cvGetSize(img_8uc1), 8, 1 );
IplImage* img_8uc3 = cvCreateImage( cvGetSize(img_8uc1), 8, 3 );
cvThreshold( img_8uc1, img_edge, 128, 255, CV_THRESH_BINARY );
CvMemStorage* storage = cvCreateMemStorage();
CvSeq* first_contour = NULL;
int Nc = cvFindContours(
img_edge,
storage,
&first_contour,
sizeof(CvContour),
CV_RETR_LIST // Try all four values and see what happens
);
int n=0,k;
printf("\n\nHit any key to draw the next contour, ESC to quit\n\n");
printf( "Total Contours Detected: %d\n", Nc );
for( CvSeq* c=first_contour; c!=NULL; c=c->h_next ) {
cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
cvDrawContours(
img_8uc3,
c,
CVX_RED, //Yarg, these are defined above, but not in the book. Oops
CVX_BLUE,
0, // Try different values of max_level, and see what happens
2,
8
);
printf("Contour #%d\n", n );
cvShowImage( argv[0], img_8uc3 );
printf(" %d elements:\n", c->total );
for( int i=0; i<c->total; ++i ) {
CvPoint* p = CV_GET_SEQ_ELEM( CvPoint, c, i );
printf(" (%d,%d)\n", p->x, p->y );
}
if((k = cvWaitKey()&0x7F) == 27)
break;
n++;
}
printf("Finished all contours. Hit key to finish\n");
cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
cvShowImage( argv[0], img_8uc3 );
cvWaitKey(0);
cvDestroyWindow( argv[0] );
cvReleaseImage( &img_8uc1 );
cvReleaseImage( &img_8uc3 );
cvReleaseImage( &img_edge );
return 0;
}
ASKER
Added file names to Linker options. It compiles now.
I checked created dll, it exports my main2 function.
I try to use it so I created test program:
***
#pragma comment(lib, "source.lib")
#include <iostream>
#include "C:\Documents and Settings\pan.james\My Documents\Visual Studio 2008\Projects\DLL\source\s ource\sour ce\dll_tut orial.h"
int main()
{
char * argument[2];
std::cout << Add(23, 43) << std::endl; // call and print the result of Add() from DLL
Function(); // call Function() from DLL
argument[0] = "";
argument[1] = "";
main2(2, argument);
std::cin.get(); // Wait for input to prevent opening then closing immediately
return(1); // return success
}
It does not compile.
I get error:
dll_test_implicit.obj : error LNK2019: unresolved external symbol _main2 referenced in function _main
panJames
I checked created dll, it exports my main2 function.
I try to use it so I created test program:
***
#pragma comment(lib, "source.lib")
#include <iostream>
#include "C:\Documents and Settings\pan.james\My Documents\Visual Studio 2008\Projects\DLL\source\s
int main()
{
char * argument[2];
std::cout << Add(23, 43) << std::endl; // call and print the result of Add() from DLL
Function(); // call Function() from DLL
argument[0] = "";
argument[1] = "";
main2(2, argument);
std::cin.get(); // Wait for input to prevent opening then closing immediately
return(1); // return success
}
It does not compile.
I get error:
dll_test_implicit.obj : error LNK2019: unresolved external symbol _main2 referenced in function _main
panJames
Hm - how did you declare the 'main2' for export/import? For implicit use (as you use it in your EXE) you have to add it in the header in the 'extern "C" ...' block similar to the functions 'Add' and 'Function', also prefixed with 'DECLDIR'. If you want to be able to load the function using 'LoadLibrary' and 'GetProcAddress' you also have to add it in the .DEF file.
ASKER
Please have a look at the code below.
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
//Some defines we left out of the book
#define CVX_RED CV_RGB(0xff,0x00,0x00)
#define CVX_GREEN CV_RGB(0x00,0xff,0x00)
#define CVX_BLUE CV_RGB(0x00,0x00,0xff)
#include <iostream> // Access to std::cout and std::endl
#define DLL_EXPORT // DECLDIR will perform an export for us
#include "dll_tutorial.h" // Include our header, must come after #define DLL_EXPORT
// Example 8-3. Finding and drawing contours on an input image
extern "C" // Get rid of name mangeling
DECLDIR int main2(int argc, char* argv[]) {
cvNamedWindow( argv[0], 1 );
IplImage* img_8uc1 = NULL;
//Changed this a little for safer image loading and help if not
if( argc != 2 || !(img_8uc1 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE )) ){
printf("\nExample 8_3 Drawing Contours\nCall is:\n./ch8_ex8_3 image\n\n");
return -1;
}
IplImage* img_edge = cvCreateImage( cvGetSize(img_8uc1), 8, 1 );
IplImage* img_8uc3 = cvCreateImage( cvGetSize(img_8uc1), 8, 3 );
cvThreshold( img_8uc1, img_edge, 128, 255, CV_THRESH_BINARY );
CvMemStorage* storage = cvCreateMemStorage();
CvSeq* first_contour = NULL;
int Nc = cvFindContours(
img_edge,
storage,
&first_contour,
sizeof(CvContour),
1 // Try all four values and see what happens
);
/*
#define CV_RETR_EXTERNAL 0
#define CV_RETR_LIST 1
#define CV_RETR_CCOMP 2
#define CV_RETR_TREE 3
*/
int n=0,k;
printf("\n\nHit any key to draw the next contour, ESC to quit\n\n");
printf( "Total Contours Detected: %d\n", Nc );
for( CvSeq* c=first_contour; c!=NULL; c=c->h_next ) {
cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
if (c->total > 100)
{
cvDrawContours(
img_8uc3,
c,
CVX_RED, //Yarg, these are defined above, but not in the book. Oops
CVX_BLUE,
0, // Try different values of max_level, and see what happens
2,
8
);
printf("Contour #%d\n", n );
cvShowImage( argv[0], img_8uc3 );
printf(" %d elements:\n", c->total );
for( int i=0; i<c->total; ++i ) {
CvPoint* p = CV_GET_SEQ_ELEM( CvPoint, c, i );
printf(" (%d,%d)\n", p->x, p->y );
}
if((k = cvWaitKey()&0x7F) == 27)
break;
}
n++;
}
printf("Finished all contours. Hit key to finish\n");
cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
cvShowImage( argv[0], img_8uc3 );
cvWaitKey(0);
cvDestroyWindow( argv[0] );
cvReleaseImage( &img_8uc1 );
cvReleaseImage( &img_8uc3 );
cvReleaseImage( &img_edge );
return 0;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you mate!
You really helped me!
panJames
You really helped me!
panJames
Fine, you're welcome - I'm glad I could help ...
Have a nice day,
best regards,
ZOPPO
Have a nice day,
best regards,
ZOPPO
IMO you need to tell the DLL project to link to the OpenCV library (I never used it so I unfortunateley don't know it's exact name).
Depending on compiler/OS you can either set this in the poject-/make-file or, i.e. in MS VisualStudio, tell the linker to use it by a '#pragma comment( lib, "<name of the lib>" );
Anyway if not alreay done the OpenCV library path has to be added to the LibPath the linker uses.
Hope that helps,
ZOPPO