Link to home
Start Free TrialLog in
Avatar of panJames
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
//  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;

}

Open in new window

Avatar of Zoppo
Zoppo
Flag of Germany image

Hi panJames,

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
Avatar of panJames
panJames

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\source\source\dll_tutorial.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
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.
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;

}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you mate!

You really helped me!

panJames
Fine, you're welcome - I'm glad I could help ...

Have a nice day,

best regards,

ZOPPO