|
Thanks it works fine. with UtcNow
|
|
|
|
|
Hello,
I am experiencing some link errors and would like to ask your help please.
I have a managed C++ workspace, which contains the main app (.exe) and a DLL project that it links to called Editor.dll.
The DLL contains MFC classes for the doc/view classes (e.g. CEditorDoc, CEditorView, etc).
The DLL builds fine, but the main application .exe (managed C++) produces link errors when these DLL classes are used
within it, as demonstrated below:
Linking...
WindowsApplication.obj : error LNK2028: unresolved token "public: static struct CRuntimeClass
* __stdcall CEditorDoc::GetThisClass(void)" (?GetThisClass@CEditorDoc@@$$FSGPAUCRuntimeClass@@XZ) referenced
in function "int __thiscall CWindowsApplication::InitInstance(void)"
(Please note the header files are included in the main app file where they are used too).
The link errors all seem to be related to a "GetThisClass()" function which i think seems to have trouble being
exported out of the DLL (it is a member of base class MFC). All other functions seem fine. I also have tried
using a .def file but it doesnt seem to help.
Any help would be greatly appreciated. Thanks!
modified on Wednesday, June 3, 2009 8:34 AM
|
|
|
|
|
James1976 wrote: a DLL project that it links to called Editor.dll.
Links to how? Did you link to the impost library (Editor.lib)?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for your reply.
I couldnt link the .lib (Editor.lib) as the .lib file is only generated if the DLL contains any exports, which it doesnt currently.
I cant export the function that has the link error (the GetThisClass() function) as its not in my code. Its in the MFC base-class and i cant override it in order to place a "declspec(export)" in front of it.
Also i cant export the entire class since it contains managed C++ code and so cannot be exported (only a class that does not contain managed code can be exported it seems).
Any further suggestions would be appreciated? Thanks.
|
|
|
|
|
James1976 wrote: I couldnt link the .lib (Editor.lib) as the .lib file is only generated if the DLL contains any exports, which it doesnt currently.
Then you have nothing to link to.
James1976 wrote: I cant export the function that has the link error (the GetThisClass() function) as its not in my code. Its in the MFC base-class and i cant override it in order to place a "declspec(export)" in front of it.
Then you create your own function that you can export and it calls the MFC function.
James1976 wrote: (only a class that does not contain managed code can be exported it seems).
That is not true. We use a DLL that I authored that is a mixed mode DLL that exports a native C++ class. That class is used in a native Win32 application. The native classes you export cannot use any managed types as parameters because then they would not be a native interface. However they can use managed objects in the implementation.
James1976 wrote: Any further suggestions would be appreciated?
See here[^]
|
|
|
|
|
Gracias!
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Tomorrows is FRIDAY!
|
|
|
|
|
Hi Mike, thanks for your reply.
led mike wrote: Then you create your own function that you can export and it calls the MFC function.
Even if i add my own function there will still be a compilation error due to the base-class function. I dont think this will work as the base-class function is still directly called by base-class code (that is, the GetThisClass() function is called by the IMPLEMENT_DYNAMIC macro in MFC). I cannot modify MFC to call my own newly added function.
led mike wrote: That is not true. We use a DLL that I authored that is a mixed mode DLL that exports a native C++ class. That class is used in a native Win32 application. The native classes you export cannot use any managed types as parameters because then they would not be a native interface. However they can use managed objects in the implementation
When i tried to place the "declspec(export)" declaration in front of any class that contains managed C++, it generated a compiler error. I wonder why it worked okay for you, perhaps i dont have something correct in my code? I'll double-check this, thanks.
led mike wrote: See here[^]
Thanks for your link. I have already tried most of these, including using a .def file (which seemed to accept the .def file but still displayed the linkage errors) and using the declspec(export) for the class as mentioned above.
I have a small sample project that i could email to demonstrate, if yourself or anyone else wouldnt mind taking a look? Any help would be greatly appreciated.
Thanks,
James
|
|
|
|
|
James1976 wrote: Thanks for your link. I have already tried most of these
Have you seen this[^]?
|
|
|
|
|
led mike wrote: Have you seen this[^]?
Thanks Mike i will give that a read and make sure that i have set up my DLL correctly. Perhaps there's something i have done.
Thanks again,
James
|
|
|
|
|
I have suucesfully created Manifext.xml.
DRMInitEnvironment function fails giving me the error code 0x8004cf19 i.e. E_DRM_BROKEN_CERT_CHAIN.
Following is error trace
Running sample OfflinePublishing...
The machine is already activated.
The user is already activated.
A client licensor certificate is already i
DRMInitEnvironment failed. hr = 0x8004cf19
|
|
|
|
|
Hello,
I would like to return a multidimensional array from a pointer function.But multidimensional array dimension's will be enormous.For example,width will be 500 and height will be 600.
Could you help me please?
|
|
|
|
|
Hello,
I wrote following code to return multidimensional array from pointer function.Input parameter of this function is one dimensional array, output is pointer that point multidimensional array.
double **function( array< double>^ data,int width,int height )
{int i;
double **R;
R=new double *[height];
for (i=0;i<height;i++)
{
R[i]=new double [width];
}
return R;
}
int main( void ) {
int M=2;
int N=10;
int i,j;
array< array< double >^ >^ input = gcnew array< array< double >^ >(M);
for (j=0;j<input->Length;j++){
input[j]=gcnew array<double>(N);}
double **result1;
result1 = new double *[N];
for(i=0;i<N;i++)
{result1[i]=new double [M];}
double **result2;
result2 = new double *[N];
for(i=0;i<N;i++)
{result2[i]=new double [M];}
result1=function(input[0],M,N)
result2=function(input[1],M,N)
for (i=0;i<N;i++)
{delete R[k];}
delete R;}
return 0;
}
I built this program succesfully in Visual Studio 2008.When I debug this code,the program computed result1 but during computing result2 in the function here:
R=new double *[height];
for (i=0;i<height;i++)
{
R[i]=new double [width];
}
Visual Studio give this error:
An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in stdeneme.exe Additional information: External component has thrown an exception.
Unfortunately I can't understand this error. How can I overcome of this problem?Could you help me please?
Best Regards..
|
|
|
|
|
I have a native-C++header Unmanaged.h and cpp file Unmanaged.cpp that I need to use with C#. So I am using C++ Interop to use the native files in a managed C++.NET project(CLI) and then reusing the C++.Net project in C#. The name of my managed C++ file is Managed.cpp
I am geting about 40 of the below error(similar error) for each function or variable or object I use in the header file.
error LNK2005: "class CHardwareDelegate11 * pDeckLinkInput1" (?pDelegate11@@3PEAVpDeckLinkInput1@@EA) already defined in Project.obj
Here's how my files look like--
***************Unmanaged.h*********I am not including the whole code.**********
#pragma unmanaged
#pragma once //This should work to make it defined only once
#ifndef BLACKMAGIC_H
#define BLACKMAGIC_H //This should also work to make it defined only once
#include "DeckLinkAPI.h" //External file
#include <vector>
#include <fstream>
IDeckLinkInput* pDeckLinkInput1 =NULL; /********************* These variables also generate redefined error***/
IDeckLinkOutput* pDeckLinkOutput1=NULL ; /********************* These variables also generate redefined error***/
class CHardwareDelegate1 : public IDeckLinkVideoOutputCallback, public IDeckLinkInputCallback
{
//variables
//Functions
}
class Data{
int frametoCapture[40];
}
//Class Objects declared here. /********************* These class objects also generate redefined error***/
//Variables Declared here /********************* These variables also generate redefined error***/
#endif
***************Unmanaged.cpp*********I am not including the whole code.**********
#pragma once
#pragma unmanaged
#ifndef Unmanaged_CPP
#define Unmanaged_CPP
//#include "stdafx.h" //Uncommenting commenting makes no difference.
#include "Unmanaged.h"
#include "Unmanaged.h" //Including Unmanaged.h twice gets no error from the compiler. Only including it in the C++.NET file creates error
#include <signal.h>
#include <boost thread.hpp="">
using namespace std;
#pragma unmanaged
static int SettopBoxCount;
Data Box[12];
int Data::frametoCapture[]={1,4,6,10,14,17,20,22,25,27,31,34,6+30,30+10,30+14,30+17,20+30,22+30,25+30,27+30,1+60,4+60,6+60,10+60,14+60,17+60,20+60,22+60,25+60,27+60,1+90,4+90,6+90,10+90,14+90,17+90,20+90,22+90,25+90,27+90,1+120,4+120,6+120,10+120,14+120,17+120,20+120,22+120,25+120,27+120};
//All class functions and variables defined below.
#endif
*************************Managed.cpp**************************This is the file in which error occurs************
#pragma once
#pragma managed //This makes no difference if its set to unmanaged or managed.
//#include "Unmanaged.h" ///////////////////////////////This is the line which causes the redefinition error///////////////
#pragma managed
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Hello World");
return 0;
}
All these files are in the same CLR project. The Unmanaged.cpp file option is set not to use the CLR runtime. The Managed.cpp file is set to use the CLR runtime. All the files in the project and the project itself is set not to use precompiled headers. I am working in Visual Studio 2008.
What is causing the error. This is so strange. Please help.
|
|
|
|
|
I would start by getting rid of all these lines, necause these are useless
and redundant in cpp files:
#pragma once
#pragma unmanaged
#ifndef Unmanaged_CPP
#define Unmanaged_CPP
...
#endif
#pragma once
Next, move all object/variable definitions from Unmanaged.h to
Unmanaged.cpp (Unmanaged.h is #included in more than one cpp file,
so the compiler is make more than one copy of the variables - the linker
doesn't like that, and it's ambiguous anyway).
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks. I removed the #pragmas and #ifendef's
I was able to find another solution by looking at some examples I looked at.
I actually made all the object variable definitions in the header file to another class I already had in the header file and declared them static.Is there any disadvantage in moving them to the class versus declaring them as global?????? I know global variables are not permitted in C#..and (c++.NET i think)?
I have 2 questions. Please read on.
I have another question relating to performance. My ultimate goal is to use some functions declared in Unmanaged.h in a C# program. I need to know whether this will relate in a performance issue because one of the classes I use (class Data) has a very big size in terms of variables declared and pointers declared.
So essentially my Unmanaged.h looks like this.
*******************Unmanaged.h*********************************
namepace UNMANAGEDNAMESPACE
{
class CHardwareDelegate1 : public IDeckLinkVideoOutputCallback, public IDeckLinkInputCallback
{
//variables
//Functions
//STATIC VARIABLES //These are moved inside the class now
//STATIC FUNCTIONS //These are moved inside the class now
//STATIC OBJECTS //These are moved inside the class now
}
class Data{
int frametoCapture[40];
//About 50 pointer arrays are declared in here each of size 10 bytes.
//About 30 arrays of size 1000 bytes each are declared in here
//Other objects of varying size declared here.
static EntryPointUnmanged() { //Do algorithm.
}
}
}
Now in my Managed.cpp file I did something like this:
*******************Managed.cpp*********************************
namespace Managed
{
public ref class ManagedCLR
{
public:
ManagedCLR (void)
{
pObj = new UNMANAGEDNAMESPACE.Data();
}
~ManagedCLR(void)
{
delete pObj;
}
void EntryPoint(void)
{
//pass through to the unmanaged object
pObj->EntryPointUnmanged(); //Here the managed program accesses my unmanaged program.
}
private:
UNMANAGEDNAMESPACE.Data *pObj; //Here my Unmanaged Class is referenced through a pointer.
};
QUESTION 1)So as seen above I am creating an pointer object of type UNMANAGEDNAMESPACE.Data So i guess the larger the size of UNMANAGEDNAMESPACE.Data class, the larger the memory used will be when i define pObj = new UNMANAGEDNAMESPACE.Data(). Is this true?
Now in my C# file I do the following.
.................Interface.cs...................................
//Add the CLRProject as a reference.
using ManagerCLRproject;
ManagedCLR object1=ManagedCLR();
object1.EntryPoint(); //This should start my UNMANAGED function written in UNMANAGED.H
QUESTION 2)Is there any problems in the above approach. Is there a better approach for reducing memory of the program?
I would appreciate it if you could answer my questions. Thanks.
|
|
|
|
|
jobin007007 wrote: I actually made all the object variable definitions in the header file to another class I already had in the header file and declared them static.Is there any disadvantage in moving them to the class versus declaring them as global??????
That's fine and ends up being pretty much the same thing, except as
static objects of a class, only one instance will exist. You still need to
define the static instances in ONE cpp file, or you'll get a linker unresolved
external error.
jobin007007 wrote: QUESTION 1)So as seen above I am creating an pointer object of type UNMANAGEDNAMESPACE.Data So i guess the larger the size of UNMANAGEDNAMESPACE.Data class, the larger the memory used will be when i define pObj = new UNMANAGEDNAMESPACE.Data().
I suppose it's true, but not an issue. No matter what heap an object is created on,
it's still going to take some memory.
jobin007007 wrote: QUESTION 2)Is there any problems in the above approach. Is there a better approach for reducing memory of the program?
The approach is fine, and a good way to make use of C++/CLI - to interoperate
between managed and unmanaged code. Again, memory is not an issue here...use the
memory you need and free it when you're done with it, just like any programming
Since you're ManagedCLR class holds unmanaged resources (an UNMANAGEDNAMESPACE.Data
object), you may want to implement the ManagedCLR as disposable, so you can free
the unmanaged resource(s) deterministically. (See Destructors and Finalizers in Visual C++[^])
It would look something like this:
public ref class ManagedCLR
{
private:
UNMANAGEDNAMESPACE.Data *pObj;
public:
ManagedCLR()
{
pObj = new UNMANAGEDNAMESPACE.Data();
}
~ManagedCLR()
{
this->!ManagedCLR();
}
!ManagedCLR()
{
delete pObj;
pObj = 0;
}
void EntryPoint(void)
{
pObj->EntryPointUnmanged();
}
};
When used from C# code, you can call Dsipose() to deterministically free unmanaged resources of
a ManagedCLR object. Whwn used from C++/CLI code, just use "delete".
Mark
Mark Salsbery
Microsoft MVP - Visual C++
modified on Sunday, May 31, 2009 4:48 PM
|
|
|
|
|
Thank you.
I wish there were more examples on all this. I had to spend 2 days looking up examples on the net. and then when i got nowhere I got a couple of books to help me out. Even with the books, small errors here and there would always deter me. It seems like only some people are using CLI INTEROPERABILITY and most people are using the P/Invoke approach. Since performance is critical on my program, this suits me.
|
|
|
|
|
jobin007007 wrote: most people are using the P/Invoke approach.
I suppose those people aren't able to use C++/CLI, like people who
only know C#, or don't have access to source code to do a C++/CLI
approach.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I suppose those people aren't able to use C++/CLI, like people who
only know C#, or don't have access to source code to do a C++/CLI
approach.
Yes. True. I am working with performance critical video hardware and software and at the same time I need to be able to develop GUI's at a fast pace. So I need to use with C++ with C#. I don't have any options!!
|
|
|
|
|
jobin007007 wrote: I am working with performance critical video hardware and software and at the same time I need to be able to develop GUI's at a fast pace. So I need to use with C++ with C#.
Same here.. WPF/C# for the GUI and general housekeeping stuff, and
C++/CLI to talk to my unmanaged C++ code...works sweet!
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Next, move all object/variable definitions from Unmanaged.h to
Unmanaged.cpp (Unmanaged.h is #included in more than one cpp file,
so the compiler is make more than one copy of the variables - the linker
doesn't like that, and it's ambiguous anyway).
Actually is there a way to access these global/variables that are declared in the header file that are not a part of any class but just a part of the namespace. If I move them to the cpp file my Managed.cpp will not even have access to them?
Lets say the Managed.cpp has access to these variables. How would I provide access to these variables from the C# file?
So Unmanaged.h is like this-
************************Unmanaged.h***********
namespace UNMANAGED{
class ABC{
};
}
Unmanaged.cpp is like this-
************************Unmanaged.cpp***********
namespace UNMANAGED{
//ABC definitions
int s; //I need access to these variables
int k; //I need access to these variables
}
***********Managed.cpp************
How would I get access to the variables I want?
|
|
|
|
|
jobin007007 wrote: How would I provide access to these variables from the C# file?
Provide an interface through your managed wrapper class.
Properties would work great ...
public ref class ManagedCLR
{
private:
UNMANAGED.Data *pObj;
public:
ManagedCLR()
{
pObj = new UNMANAGED.Data();
}
~ManagedCLR()
{
this->!ManagedCLR();
}
!ManagedCLR()
{
delete pObj;
pObj = 0;
}
void EntryPoint(void)
{
pObj->EntryPointUnmanged();
}
property int s
{
int get()
{
return UNMANAGED::s;
}
void set(int value)
{
UNMANAGED::s = value;
}
}
property int k
{
int get()
{
return UNMANAGED::k;
}
void set(int value)
{
UNMANAGED::k = value;
}
}
};
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I did everything that is mentioned in these posts.I created a start button in a c# Windows Forms GUI. Now when I try to call the ManagedC++ Function from C# by clicking a start button, I get this error:
Attempt to load an unverifiable executable with fixups (IAT with more than 2 sections or a TLS section.) (Exception from HRESULT: 0x80131019)
and the program crashes.
Heres my start button code:------
private void button_Start(object sender, EventArgs e)
{
BlackMagicManaged.BlackMagicCLR Result=new BlackMagicCLR();
Result.StartCapture(); //Accessing the Managed CLR class.
}
|
|
|
|
|
BlackMagicManaged.BlackMagicCLR should be in a library (DLL), not an EXE.
Issue reported to Microsft[^]...AFAIK status is still unresolved
four years later
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|