简体   繁体   中英

Using mixed DLLs from /clr:pure projects

I'm building a project along with a Dll.

The Dll must support native code so I declared it as a /clr. My project was initialy also a /clr project and everything was fine. However I'd like to include some NUnit testing so I had to switch my main project from /clr to /clr:pure.

Everything still compiles but any Dll call generates a runtime error. When I revert back to /clr everything is ok

In my Dll, exported functions are declared as follow :

#define DllExport   __declspec( dllexport )
DllExport bool DisplayScan(bool bShow, bool bAllPasses) { }

I also made a .def file containing the real names of all the exported functions

LIBRARY "Controller"
EXPORTS
DisplayScan

From my main project my imports are declared as follow :

#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool DisplayScan(bool bShow, bool bAllPasses)

Anyone ever encountered such a problem?

Ok everything is working now

In fact, it has been working from the beginning.

Moral : don't try to cast a char* into a std::string

Weird thing : its ok in /clr until you return from the function. It crashes right away in /clr:pure

Basically you are doing something that's not supported; /clr:pure and native DLL exports. As quoted from this MSDN article "pure assemblies cannot export functions that are callable from native functions because entry points in a pure assembly use the __clrcall calling convention."

I'm not sure of the best workaround. However, with a little experimenting, you could probably take advantage of the __clrcall calling convention with the /clr option. Here's a link that may be useful. From what I can gather you should be able to export those managed classes and consume them from within a managed assembly such as your managed NUnit test project, but keep your unmanaged exports there with different method signatures. Keep in mind that as soon as you expose any .net class via an export, it will need to use the __clrcall calling convention.

Advantages of /clr:pure

Better Performance: Because pure assemblies contain only MSIL, there are no native functions, and therefore no managed/unmanaged transitions are necessary. (Function calls made through P/Invoke are an exception to this rule.)

AppDomain Awareness: Managed functions and CLR data types exist inside Application Domains, which affects their visibility and accessibility. Pure assemblies are domain-aware (__declspec(appdomain) is implied for each type) so accessing their types and functionality from other .NET components is easier and safer. As a result, pure assemblies interoperate more easily with other .NET components than mixed assemblies.

Non-disk loading: Pure assemblies can be loaded in-memory and even streamed. This is essential for using .NET assemblies as stored procedures. This differs from mixed assemblies, which due to a dependency on the Windows loading mechanisms, must exist on disk in order to execute.

Reflection: It is not possible to reflect over mixed executables, whereas pure assemblies provide full reflection support. For more information, see Reflection (C++/CLI).

Host Controllability: Because pure assemblies contain only MSIL, they behave more predictably and flexibly than mixed assemblies when used in applications that host the CLR and modify its default behavior.

Limitations of /clr:pure

This section covers features not currently supported by /clr:pure.

Pure assemblies cannot be called by unmanaged functions. Therefore pure assemblies cannot implement COM interfaces or expose native callbacks. Pure assemblies cannot export functions via __declspec(dllexport) or .DEF files. Also, functions declared with the __clrcall convention cannot be imported via __declspec(dllimport). Functions in a native module can be called from a pure assembly, but pure assemblies cannot expose native-callable functions, so exposing functionality in a pure assembly must be done through managed functions in a mixed assembly. See How to: Migrate to /clr:pure (C++/CLI) for more information.

ATL and MFC libraries are not supported by pure mode compilation in Visual C++.

Pure .netmodules are not accepted as input to the Visual C++ linker. However, pure .obj files are accepted by the linker, and .obj files contain a superset of information contained in netmodules. See .netmodule Files as Linker Input for more information.

Compiler COM support (#import) is not supported, as this would introduce unmanaged instructions into the pure assembly.

Floating point options for alignment and exception-handling are not adjustable for pure assemblies. As a result, __declspec(align) cannot be used. This renders some header files, such as fpieee.h, incompatible with /clr:pure.

The GetLastError function in the PSDK can give undefined behavior when compiling with /clr:pure.

your problem is calling conventionCallingConvention = CallingConvention::Cdecl ... define your function like that or use stdcall or clrcall, clecl is for pure C

or problem is here: define that function extern not static

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM