0

I get these three errors and they seem to make little sense to me. If i comment the UserInstruction1(P1, P2, P3); in the console app the errors go away. Both projects are /CLR projects.

error LNK2028: unresolved token (0A000930) "void __cdecl UserInstruction1(double *,wchar_t *,wchar_t *)" (?UserInstruction1@@$$FYAXPANPA_W1@Z) referenced in function "int __cdecl wmain(int,wchar_t * * const)" (?wmain@@$$HYAHHQAPA_W@Z)  

error LNK2019: unresolved external symbol "void __cdecl UserInstruction1(double *,wchar_t *,wchar_t *)" (?UserInstruction1@@$$FYAXPANPA_W1@Z) referenced in function "int __cdecl wmain(int,wchar_t * * const)" (?wmain@@$$HYAHHQAPA_W@Z)

error LNK1120: 2 unresolved externals   C:\Workspace\Company.Pins\Bank\Source\Debug\Company.Pins.Bank.Win32Console.exe

//Console App.
#include "stdafx.h"
#include "UInstruction.h"



int _tmain(int argc, _TCHAR* argv[])
{
    auto P2 = (TCHAR *)"3 Barrowstead";
    TCHAR* P3;
    double* P1;
    P1[0] = 13;

    UserInstruction1(P1, P2, P3);
    return 0;
}

--

//UInstruction.h
#ifndef __UINSTRUCTION_H__
#include "stdafx.h"
#include "UInstruction.h"
#include "common.h"

#include <iostream>
#include <stdio.h>
#define PRES_NOCOMMAND_FOUND 2000


#define DllExport  __declspec(dllexport)

void ReconcileUHParameter(const double* lpNumeric, TCHAR* lpAlpha1, TCHAR* lpAlpha2);
extern void UserInstruction1(double* lpNumeric,     TCHAR* lpAlpha1, TCHAR* lpAlpha2);

#endif

--

//UInstruction.cpp
#include "stdafx.h"
#include "UInstruction.h"
#include "common.h"
#using "Company.Pins.Bank.Decryption.dll"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;


CPReSInterfaceApp theApp;
extern void UserInstruction1(
                    double* lpNumeric, 
                    TCHAR* lpAlpha1, TCHAR* lpAlpha2)
{
//logic goes here       
}
Andy
  • 2,248
  • 7
  • 34
  • 57
  • Why do you include Uinstruction.h in Uinstruction.h? That doesn't make sense. And you should allocate your `double*` before using it. – RedX Apr 15 '11 at 15:02
  • http://msdn.microsoft.com/en-us/library/fzaatbst.aspx – DumbCoder Apr 15 '11 at 15:03
  • Linker error means compiler found it's declaration but linker failed to find it's definition while binding the executable. The point of definition of `UserInstruction1` doesn't need to mention it is `extern`. – Mahesh Apr 15 '11 at 15:04
  • including stdafx.h in the UInstruction.h is not necessary, #include "UInstruction.h" is also unnecessary and makes no sense, including and most probably should be done through stdafx.h since they never change are probably often used and it saves you the typing of the includes all over the place... – ds27680 Apr 15 '11 at 15:48
  • Did you try Google for these `LNK` error messages? Usually the first hits explains in detail what they mean. – default Apr 15 '11 at 17:52

2 Answers2

2

I assume here that all code resides in a single project (Company.Pins.Bank.Win32Console). If so you should move the <\iostream> and <\stdio.h> includes (and any other includes of headers that never/seldom change to stdafx.h:

//stdafx.h

#include <iostream>
#include <stdio.h>


//other headers that are widely used but never/seldom change...

#define DllExport  __declspec(dllexport)
#define DllImport  __declspec(dllimport)

and

//UInstruction.h

#pragma once //you are in VS 2010...

#include "common.h"

//ommited code for brevity...
void UserInstruction1(double* lpNumeric,     TCHAR* lpAlpha1, TCHAR* lpAlpha2);

and

//UInstruction.cpp
#include "stdafx.h"
#include "UInstruction.h"

//ommitted code for brevity...

void UserInstruction1( double* lpNumeric, 
                       TCHAR* lpAlpha1, TCHAR* lpAlpha2 )
{
   //logic goes here
}

If UserInstruction1 resides in a Dll that is used by the Company.Pins.Bank.Win32Console project:

Make sure you define in stdafx.h for the dll and console projects:

#define DllExport  __declspec(dllexport)
#define DllImport  __declspec(dllimport)

Open the properties for the DLL project, go to "Configuration Properties" -> "C/C++" -> "Preprocessor" and add to "Preprocessor Definitions" a preprocessor symbol (if you don't have one). I.e. I'll call it MY_DLL. Don't forget to define it in all configurations...

Make sure you export the functions from the Dll

//UInstruction.h

#pragma once //you are in VS 2010...

#ifdef MY_DLL
    #define MY_DLL_EXPORTS  DllExport
#else
    #define MY_DLL_EXPORTS  DllImport
#endif //MY_DLL

#include "common.h"

#define PRES_NOCOMMAND_FOUND 2000

//ommited code for brevity...

void MY_DLL_EXPORTS UserInstruction1(double* lpNumeric,     TCHAR* lpAlpha1, TCHAR* lpAlpha2);

The cpp file for UInstruction remains the same as above...

EDIT: For completness...

//UInstruction.cpp
#include "stdafx.h"
#include "UInstruction.h"

//ommitted code for brevity...

//no extern needed...
void UserInstruction1( double* lpNumeric, 
                       TCHAR* lpAlpha1, TCHAR* lpAlpha2 )
{
   //logic goes here
}

Do not forget to add a reference to the Dll project to the Company.Pins.Bank.Win32Console project from the properties of the Company.Pins.Bank.Win32Console "Common Properties" -> "Framework and References"

ds27680
  • 1,993
  • 10
  • 11
  • ah my bad, i should have said. The console and the UInstruction are in diffrent projects, but i have referenced the UInstruction project as told here http://stackoverflow.com/questions/5674827/how-can-you-all-a-method-from-a-diffrent-project-both-in-c – Andy Apr 15 '11 at 15:43
  • @Andy Yes but I already detailed a solution for the case when UserInstruction1 resides in a Dll that is used by the Company.Pins.Bank.Win32Console project. Please see above – ds27680 Apr 15 '11 at 15:50
  • Following all this has solved the 2028 but i still have the 2019 error. been looking at that one for a while and can't seem to solve it. – Andy May 03 '11 at 13:52
  • @Andy Well if you can send me the two projects as zip per e-mail I might be able to help you further... At this time it is not clear for me what types of projects (native, managed, mixed) are we talking about and what are you missing to get them to link successfully. ds27680@gmail.com – ds27680 May 03 '11 at 19:13
2

You are trying to use a function in a project that's compiled with the /clr option. Managed code. From a console application project that's compiled without the /clr option. Native code. You are getting the linker error because it is looking for a __cdecl function, it is actually compiled as a __clrcall function.

That's just the linker problem, there's also a runtime problem because your console app doesn't have the CLR loaded and initialized, ready to execute managed code. You need to consider how you are going to interop with managed code. The obvious solution is to make your console app a managed app as well. Or to make your DLL an unmanaged one, you are not making any obvious use the .NET framework. Or you can complicate your life by hosting the CLR in your native app (google CorBindToRuntimeEx()) or turning your DLL into a COM server.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I'm using the /clr on both of the projects yet its giving me this error. is there something else i need to de before it will work? – Andy Apr 18 '11 at 10:10
  • The console project is being compiled without /clr, the linker error clearly shows it. Note the __cdecl calling convention for the function. It would be __clrcall if it was parsed by the managed code compiler. This mixing and matching is getting you in trouble, I *strongly* recommend you either write pure managed code or pure native. Right now, pure native is the kind of code you are writing. – Hans Passant Apr 18 '11 at 12:28
  • the code needs to be managed for later purposes. i added /clr to both projects command line before i even got to this stage. Is there a reason why it would ignore this /clr? (i had to change quite some parameters before it would stop crashing on the adding of /clr.) – Andy Apr 18 '11 at 14:51
  • 1
    If this is intended to be all /clr compiled then be sure to write code inside a "ref class" and to use Project + Properties, Common Properties, Framework and References, Add New Reference to add a reference to the class library project. .NET assemblies are not linked at build time, it happens at runtime. – Hans Passant Apr 18 '11 at 16:08