[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 614
  • Last Modified:

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

0
panJames
Asked:
panJames
  • 4
  • 3
1 Solution
 
ZoppoCommented:
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
0
 
panJamesAuthor Commented:
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
0
 
ZoppoCommented:
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.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
panJamesAuthor Commented:
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

0
 
ZoppoCommented:
You have to declare it in the header 'DLL_Tutorial.h' - further I forgot to mention that in that header the 'DECLDIR' should be declared differently when used in the DLL or in the EXE project - therefor you should declare a preprocessor define in the projects C++->Preprocessor settings of the DLL project like 'MY_DLL_EXPORTS' - then use this define to declare the functions as 'dllexport' when building the DLL and as 'dllimport' when using thew header in the EXE.

So the relevant part of the header should look somehow like this:

> #ifdef MY_DLL_EXPORTS
> #define DECLDIR __declspec(dllexport)
> #else
> #define DECLDIR __declspec(dllimport)
> #endif
> extern "C"
> {
>    DECLDIR int Add( int a, int b );
>    DECLDIR void Function( void );
>    DECLDIR int main2(int argc, char* argv[]);
> }
0
 
panJamesAuthor Commented:
Thank you mate!

You really helped me!

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

Have a nice day,

best regards,

ZOPPO
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now