Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / January 2005

Tip: Looking for answers? Try searching our database.

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

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Gustavo L. Fabro - 05 Jan 2005 13:07 GMT
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!
Ian Lazarus - 06 Jan 2005 00:34 GMT
These two titles in the docs might help.

"Accessing C++ Code from .NET Framework Objects"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/v
cmg_accessingcodefromframeworkobjects.asp


"Platform Invocation Services"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/v
cmg_PlatformInvocationServices.asp

Gustavo L. Fabro - 06 Jan 2005 19:28 GMT
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,

>"Platform Invocation Services"
>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/v
cmg_PlatformInvocationServices.asp

>,

>*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
Ian Lazarus - 06 Jan 2005 22:54 GMT
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.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.