'Unresolved External' when calling unmanaged DLL from managed Windows Forms executable

  • Thread starter Gustavo L. Fabro
  • Start date
G

Gustavo L. Fabro

Greetings!

I'm a newbie in Visual C++ .NET (have programmed in Borland C++
and Builder for long) and I am trying to do a very simple thing,
but I'm stuck.

I created an (unmanaged) DLL project with a sample function, and
tried to call it from a ".NET Forms" project. All I get are
"Unresolved External" errors from the Linker!

When I try to call the same functions from a "Pure Win32" or a
Console Application, everything works well!

What could be happening? I'm sure it's something very trivial
and silly, but I'm stuck!

What I've done so far:

- Created the DLL, using Visual Studio default macros
- Exported the class contained in the DLL that I want to use.
- Compiled the DLL, OK
- Created a Windows Forms project, with one button that tried to
instantiate the class defined in the DLL and call its function.

Configurations for the Windows Forms Executable Project:
C/C++
General - Additional Include Directories: ..\DrawDll
Linker
General - Additional Library Directories: ..\DrawDll\Release
Input - Additional Dependencies:
...\DrawDll\Release\DrawDll.lib

I have 2 projects in the solution, each one on its own directory.

That's all that was necessary for the Console AND for the Win32
versions to work! However, on this project I'm getting:

Form1.obj : error LNK2001: unresolved external symbol "public:
__thiscall Project::CDrawDll::CDrawDll(void)"
(??0CDrawDll@Project@@$$FQAE@XZ)
Form1.obj : error LNK2001: unresolved external symbol "public: void
__thiscall Project::CDrawDll::MyMethod(void)"
(?MyMethod@CDrawDll@Project@@$$FQAEXXZ)

Any clues?

Here are the files being used:

DrawDll.h
#ifdef DRAWDLL_EXPORTS
#define DRAWDLL_API __declspec(dllexport)
#else
#define DRAWDLL_API __declspec(dllimport)
#endif

// This class is exported from the DrawDll.dll
class DRAWDLL_API CDrawDll {
public:
CDrawDll(void);
void MyMethod(void);

};

DrawDll.cpp
#include "stdafx.h"
#include "DrawDll.h"
#include <stdio.h>

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;
}

void CDrawDll::MyMethod(void)
{
OutputDebugString("It Worked!");
}


The Project.cpp and Project.h files are just the default
"Windows Forms Application (.NET)" generated files, plus
the code to try and run the DLL:

Form1.h
#include <windows.h>
#include <stdio.h>
#include "DrawDll.h"

public __gc class Form1 : public System::Windows::Forms::Form

....

private: System::Void button1_Click(System::Object * sender,
System::EventArgs * e)
{

CDrawDll lala;
lala.MyMethod();
}

Form1.cpp
#include "stdafx.h"
#include "Form1.h"
#include <windows.h>

using namespace Project;

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
System::Threading::Thread::CurrentThread->ApartmentState =
System::Threading::ApartmentState::STA;
Application::Run(new Form1());
return 0;
}

Thanks for any help!
 
G

Gustavo L. Fabro

Greetings! Thank you very much for some reply. I wonder if my question is
so obvious nobody cared to answer or if, theoretically, I was doing things
right and it should be working, so things are more complicated!

As said on the 2nd link,
*An important and unique feature of Managed Extensions for C++ is that you
can use unmanaged APIs directly. Data marshaling is handled automatically.
If you do not require customized data marshaling, you do not need to use
PInvoke. *

This is what I actually want to do. I'm using Managed Extensions for C++! My
Executable project is in C++, not on C#, Visual Basic or
any other language. Should the marshaling still be necessary?

*
Advantages of IJW There is no need to write DLLImport attribute
declarations for the unmanaged APIs the program uses. Just include the
header file and link with the import library.
*

There, I've included the header file and included the .LIB file. Isn't that
what I am really supposed to do? Am I doing something wrong?

I checked the .DLL file with depends.exe and found out the decorated name
for the function is

'?MyMethod@CDrawDll@@QAEXXZ,

but the linker error mentions

"public: void __thiscall Project::CDrawDll::MyMethod(void)"
(?MyMethod@CDrawDll@Project@@$$FQAEXXZ)'

Could this @Project@ reference be the reason why it isn't resolving the
symbol? "Project" is the name I gave for the 'Windows Forms Executable"
project, that tries to use the DLL.

Thanks for any help!

Gustavo
 
I

Ian Lazarus

I'm in the same boat as you. I'm just beginning to learn C++ with extension,
and the first thing I tried is to call a C++ class which is located in a
DLL. I looked high and low and found no help in how to do so. That's
probably why one of those links limits itself to directly calling functions
in a DLL. I finally came to the conclusion that it is not possible, which is
probably why the other link suggested wrapping the C++ class, which is what
I am finally now doing. As an aside, in case it is helpful, my wrapping
class only exposes managed types, e.g., Int32, IntPointer, etc. I am
handling any necessary marshalling with my own code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top