1

I have an Assembly(A) which defines a Managed class which has a public constructor that takes two native types.

I have access to the Header files and compiled lib files which contain the native types.

I created a C++/CLI project and defined a ref class which contains a single public: static method that returns a public type defined in (A).

When I try to contstruct by passing in a native type I receive the `C3767 'YourType::TypeB': Candidate function(s) not accessible.

I've added #pragma make_public(Type) for the native types and any type they derive from but still not joy.

My class header:

#pragma once
#include "StdAfx.h"

using namespace System;
using namespace AssemblyA;

namespace NativeWrapper {
    ref class MyFactory
    {
    public:
        static AssemblyAType^ Build();
    };
}

My cpp file:

#include "StdAfx.h"

#pragma make_public(nativeObjectRoot)
#pragma make_public(nativeObjectDerived)


#include "MyFactory.h"

using namespace System;

using namespace NativeWrapper;

AssemblyAType^ MyFactory::Build()
{
  nativeObjectDerived* myNativeObject;
  //myNativeObject initialised and set up here
  return gcnew AssemblyAType(myNativeObject); <--C3767
}

I've looked and the managed type `AssemblyAType' has a public constructor with this signature. Can't seem to get the pragma to work??

So to summarize.

My C++/CLI project references a 3rd party Assembly that defines a type which takes a native type in its constructor. My project also has the header/lib files added/linked to.

Note: my code above isn't exactly what I've got but I've stripped out the pertinent parts.

Matt Smith
  • 17,026
  • 7
  • 53
  • 103
MattC
  • 3,984
  • 1
  • 33
  • 49

1 Answers1

2

make_public will make the the native type visibile to consumers of the assembly where you use it: http://msdn.microsoft.com/en-us/library/ms235607(v=vs.80).aspx. It will not change the visibility in an assembly you reference.

It seems the assembly you referenced should have had either a make_public for the native type, or simply declared the native type public (see Type visibilty for a header Share a header file shared between native and managed clients).

The below page seems to indicate that they should have gotten a warning for writing the method without making the native types public: http://msdn.microsoft.com/en-us/library/ms173713(v=vs.80).aspx

Perhaps you could post the third-party AssemblyAType code to make sure there's nothing else we're missing.

Community
  • 1
  • 1
Matt Smith
  • 17,026
  • 7
  • 53
  • 103
  • I have access to the header files and I've changed the classes to be public yet `#pragma make_public(type)` still didn't work. – MattC Feb 09 '12 at 19:02
  • The method you are accessing is a manged method--not a native method, so it is finding the method via your reference to the assembly and that assemb's metadata (it's not using the header to find it). So in Assembly A, the native type must be public (either via make_public or or by a normal use of public). If you can't modify AssemblyA, I think you are out of luck. – Matt Smith Feb 09 '12 at 22:07
  • So, if you have access to AssemblyA's source, you'd need to make the native types public (either by prepending them with public or using make_public), and then build AssemblyA. Then when you reference AssemblyA, those types will be public. – Matt Smith Feb 09 '12 at 22:09
  • OK, I see. AssemblyA and my assembly both use the native library and AssemblyA is provided as is (built on top of the native library then given to me). So from what you are saying, I'm out of luck. – MattC Feb 10 '12 at 18:39
  • I think so. Whoever made AssemblyA should have received a warning when they compiled it. I think you could call the method even though you don't have "access" to it by using reflection (though, I doubt you'd want to take that approach). – Matt Smith Feb 10 '12 at 20:38