I am making a computer app in C++/CLR and I just hit the wall. I'm loading the dll using the loadlibrary function and I am able to call the functions too but when I try to send a parameter for example if my function is:
std::string msgbox(std::string str)
{
MessageBoxA (0,str.c_str(),"TiTle", MB_OK | MB_ICONINFORMATION);
return str;
}
In a native c++ app when I call the function after loadlibrary and getprocaddress
std:: tmp = msg ("String");
tmp becomes "String"; and I see a Message box with String as the message but if I use C++/CLR I get like some rubbish while printing the message content in the message box if I pass in a parameter and the tmp variable would contain some trash text too how can I just load it the same way as I am doing but without this trash in the way
This is the output and the source code too:
Source: https://uploadfiles.io/itm93
Error images: https://imgur.com/a/WM7MK4c
It looks like you are compiling your c++ dlls with gcc. You can't pass standard library types between DLLs/applications compiled against different standard libraries.
You either need to compile everything with visual studio (and the same runtime library, you can't mix debug/release or the static/shared runtimes) or only pass raw character pointers over dll boundaries.
Related
I am trying to use LAME in Unity3d on OS X with Mono c#. I dragged the Lame_enc.dll in but when the wrapper tries to find it, it doesn't and i get
DllNotFoundException: Lame_enc.dll
Yeti.MMedia.Mp3.Mp3Writer..ctor (System.IO.Stream Output, WaveLib.WaveFormat InputDataFormat, Yeti.Lame.BE_CONFIG Mp3Config) (at Assets/Helping Libraries/Lame/Mp3Writer.cs:82)
The problem from what i see, it when i try to 'link' some static methods to the dll:
[DllImport("Lame_enc.dll")]
public static extern uint beInitStream(BE_CONFIG pbeConfig, ref uint dwSamples, ref uint dwBufferSize, ref uint phbeStream);
I know that in order to see dll, on Windows, the dll needs to be in the same folder as the .exe file, but Unity being a multiplatform solution, i don't know how i can tell it where it is.
I've placed the dll in my project root folder, in the Library, in the Editor, but no luck!
Just remove the ".dll",it will work well in Editor,but won't work on mobile phone.I removed the using xxx.window and some unused files,but still the output file xx.mp3 only has 44B.
I'm migrating an old OWL application to MFC. there were a main library that has the main dialogs and controls , I started writing an alternative classes of MFC to the old OWL like TDialog[inherits from CDialogEx], TEdit..... I added all the needed classes from the OWL now my library build successfully.
I created a new MFC Application [to test the library], i exported a function [SowDialogue] from the dll to be used in the Application , I added the .lib of dll to the MFC application, I called the function to show a simple dialog , the build go successfully, but at the first start the application fail with the following message
I clicked retry and the break to get the line that caused the assertion it was that one
So the problem is with the resources. when i link with the library the MFC can't get the right resources module.
I thought it was because i use a regular dll that uses MFC and shares MFC objects, if i must use an MFC extension library. how can i convert regular library to MFC extension library.
Or any solution to this disaster after a long work
EDIT
this is the call stack, there are no exported functions in this, its all in the application the error come before calling anything from the dll
Solution
the problem was solved when i converted the dll to an MFC extension library, really i created a new mfc extension dll and cheated it's properties, the dll main, the stafx includes and preprocessors definisions
static AFX_EXTENSION_MODULE MFCExtensionDLL = { NULL, NULL };
extern "C" int APIENTRY DllMain( HINSTANCE hInst, DWORD fdwReason, LPVOID)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
TRACE0("MFCExtension.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(MFCExtensionDLL, hInst))
return 0;
new CDynLinkLibrary(MFCExtensionDLL);
//My initialization code
return 1;
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
// Terminate the library before destructors are called
AfxTermExtensionModule(MFCExtensionDLL);
// my finalization code
return 1;
}
}
the properties
in the properties of project->configuration properties->general Use of MFC = Use MFC in a Shared DLL
,
in the properties of project->configuration properties->C/C++->Preprocessor->Preprocessor Definitions->add _AFXEXT , make sure to delete _USERDLL if it exists
When using MFC in a .dll, you have to make sure that the .dll can find resource handles for things like strings and bitmaps in the .rc file. MFC maintains an internal state for each .dll that points to the resources for that .dll. When calling into that .dll from an application (or another .dll) you have to 'help' MFC get the internal state right or it will not be able to find your resource and will ASSERT.
I can't see the function immediately below the one in the call stack in your example, but if it is an exported function, the MFC state problem is likely what is going on.
Make sure you have put the AFX_MANAGE_STATE macro at the top of any functions accessible from outside (exported functions). That will go a long way to solving your problems.
Microsoft reference: http://msdn.microsoft.com/en-us/library/ba9d5yh5(v=vs.80).aspx
If you use resources or windows from a dll file, you can try this way. This code can be in the dll itself. Whenever the resource is created the current resource handle of the main process will be set as the dll's resource handle and use the handle.
After any window creation or resource change revert it back to the old value.
hdllresource = ::LoadLibrary(<dllfile containing the resource>);
hcurrentInst = AfxGetResourceHandle();
AfxSetResourceHandle(hdllresource );
//do your window creation or resource loading stuff
AfxSetResourceHandle(hdllresource);
I am using some third party software to aid in writing an iPad application using Xcode 4.3.2. The software is open source and is usually set up so its code will be compiled along with whatever code the developer writes for the application. Because I was using the software in numerous places, I decided to build it as a static library for the iOS simulator.
I was able to build the library, and convert one application to link to that library instead of compiling the original source code. However, when I go to run the application on the simulator, I get an error that says, unrecognized selector sent to instance.
I have verified that the program is successfully using portions of the static library. However, there is one piece of code that tries to call a method on an object, and that where the failure occurs. The method being called is not actually defined in the interface of that object. Rather it is provided in an additional module that defines a category for that object's class. The header file for that module is properly included and the compiler should have been able to find the category method and apply it to the object, yet at run time, the error mentioned above occurs.
I used the 'nm' command to verify that the category method exists in the static library. Here is an example of the output:
nm libStaticLibrary.a | grep categoryMethod
00000130 t -[SomeClass(Category) categoryMethod:]
0000354c s -[SomeClass(Category) categoryMethod:].eh
What ideas do people have about how this library can be made to work correctly with the desired application?
Your 3rd party framework is probable using a category on a existing (apple) class. But to load/find the category you need to add the -ObjC flag in the build settings under Other Linker Flags
Pfitz answer is great, but this will cause the compiler to load a bunch of unused binaries to your project which is not what you want. Please refer to this answer to know why https://stackoverflow.com/a/22264650/1363997
Here is the best solution:
1) select your project target from the left panel (the folders navigator)
2) select "Build Phases" tap
3) expand "Compile Sources" cell
4) hit the plus button at the bottom and then add your category's .m file
Done!
Note: you have to search for the file by navigating through the folder by your self, don't type the file's name in the search field
I have a header file that is included by both a native cpp file and a managed cpp file(compiled with /clr). It includes only native types, but I want to specify that the native types are visible outside the assembly
(see http://msdn.microsoft.com/en-us/library/4dffacbw(VS.80).aspx).
Essentially, I want:
public class NativeClass // The public makes this visible outside the assembly.
{
};
If I include this code from a native cpp, I get the following error:
error C3381: 'NativeClass' : assembly access specifiers are only available in code compiled with a /clr option
Attempted solution:
I'm currently using a preprocessor solution that causes the public to appear when compiling with the managed client, but it does not appear for the native client:
#ifdef __cplusplus_cli
#define CLR_ASSEMBLY_ACCESS_SPECIFIER__Public public
#else
#define CLR_ASSEMBLY_ACCESS_SPECIFIER__Public
#endif
CLR_ASSEMBLY_ACCESS_SPECIFIER__Public
class NativeClass
{
};
Question:
Is this the appropriate way to achieve this, or is there a better way?
Have you tried the make_public pragma listed on the MSDN page you linked to?
Otherwise, the solution you have is perfectly valid. I'm curious to know why you want to export native types from a CLR assembly though.
I downloaded the class files and demo program here: http://github.com/matej/MBProgressHUD
When I try to compile the program, I get several errors. The first one appears here:
CG_EXTERN void CGPDFContextAddDocumentMetadata(CGContextRef context,
CFDataRef metadata) CG_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_0);
On the second line the error is "Expected function body after function declarator."
What's wrong with this code? How can it be fixed?
In the project build settings, change the compiler version to the system default.
If you have access to Apple's Dev Forums for the Xcode betas, you can find more info and an alternative solution at https://devforums.apple.com/message/287160#287160.