Candidate function(s) not accessible [?]

A

ajtaylor

Hello,

Sorry another question on mixed code assemblys.

I have a static class library containing a lot of unmanged code.

I have created a mixed code assembly which I am attempting to use in a
forms project.

Thus,

Class Library:

"Types.h"

class someType
{
public:
someType(double val);
//load of unmanaged stuff
};

//////////////////////////////////////////////////

CLR Library:

#include "Types.h"

using namespace System;

namespace CLRLibrary {

public ref class MyAssembly
{
public:
MyAssembly(const someType& val);

private:
someType m_value;
};
}

//////////////////////////////////////////////////
Forms project:
#include "Types.h"
double val = System::Convert::ToDouble(textBox1->Text);
CLRLibrary ::MyAssembly^ ass = gcnew CLRLibrary
::MyAssembly(someType(val));

//////////////////////////////////////////////////

Now, I cant see any reason why this wouldnt work - indeed this seems
like a perfectly reasonable thing to want to do.

Problem is when I build the solution I get:-

Form1.h(100) : error C3767: 'CLRLibrary::MyAssembly::MyAssembly':
candidate function(s) not accessible

Can anyone point me in the correct direction please? I have to admit to
getting a bit frustrated with C++/CLI
 
H

Holger Grund

class someType
{
public:
someType(double val);
//load of unmanaged stuff
};

//////////////////////////////////////////////////

CLR Library:

#include "Types.h"
It's important to understand that in the CLR type
identity is comprised of the definining assembly and its full
name.

The C++ compiler translates native types (such as someType)
to CLR value types.

When you share an include file between two different projects
(or actually between two projects generating different PE modules),
you end up with two distinct value type definitions.
using namespace System;

namespace CLRLibrary {

public ref class MyAssembly
{
public:
MyAssembly(const someType& val);

By default, CLR value types emitted for native types are not exported.
That means there is no way (well, sort of) to refer to these from outside
the assembly.
Forms project:
#include "Types.h"
double val = System::Convert::ToDouble(textBox1->Text);
CLRLibrary ::MyAssembly^ ass = gcnew CLRLibrary
::MyAssembly(someType(val));
Form1.h(100) : error C3767: 'CLRLibrary::MyAssembly::MyAssembly':
candidate function(s) not accessible
I believe, the diagnostic tries to tell you that the ctor
is not accessible because on type in the signature is not visible
outside the assembly.

Consider the following example:

//t.cpp
struct N{};
public ref struct R { R( N* ){} };
// u.cpp
int main() { R r(0); }

// /clr:safe suppress a lot of metadata - you'll better understand ILDASM
cl /clr:safe /LD /wd4956 /wd4959 t.cpp
cl /clr /FUt.dll u.cpp
Can anyone point me in the correct direction please? I have to admit to
getting a bit frustrated with C++/CLI
You should try to avoid native types in managed signatures. Just use
standard C++ techniques (i.e. static libraries & header files) or
create wrappers for your types.

You can still use some hack to make the C++ compiler-generated
value type public (i.e. visible outside the assembly). But then you
shouldn't use #include to introduce your interface.

You can use a visibility specifier on your native types (i.e.:
public class someType{..}; )
and there's the make_public pragma.

-hg
 
A

ajtaylor

Holger said:
You should try to avoid native types in managed signatures. Just use
standard C++ techniques (i.e. static libraries & header files) or
create wrappers for your types.

You can still use some hack to make the C++ compiler-generated
value type public (i.e. visible outside the assembly). But then you
shouldn't use #include to introduce your interface.

You can use a visibility specifier on your native types (i.e.:
public class someType{..}; )
and there's the make_public pragma.

-hg

Many thanks for your reply.

I am having problems getting my head around how one would "properly"
design something using C++/CLI when using libraries of unmanaged code.

As I saw it I can create my static libraries of unmanaged code and then
create a series of assemblies that use this code but provide a managed
interface to this that refer to unmanged types.

I really dont want to provide a C++/CLI mapping class for each of the
unmanged types nor make these types managed.

For example I have a unmanaged struct that is used a lot in my
unmanaged library that contains a large number of ints/doubles that
seems a perfect candidate to be used in a managed function signature as
it isnt too complicated and to duplicate this structure in managed code
just so it can be used in a function signature seems *wrong*.

I have used make_public and my code compiles and links ok. But I am
concerned that this isnt a proper design solution.
 

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