I feel so dumb asking this question but honestly I can't understand why System namespace can't be used! What am I doing wrong? Is there any other way to print a single line in the output?
(I am using Visual Studio 2015)
I can't understand why System namespace can't be used
Windows Universal app is totally different with traditional desktop app, please check Windows Runtime APIs and Win32 and COM API which lists all Win32 and COM APIs supported for use in UWP apps.
Is there any other way to print a single line in the output? (I am using Visual Studio 2015)
If you need to print message to Output window, use OutputDebugString function in UWP C++/CX project, adding #include to access it, for example:
void CPPUWPApp1::MainPage::LogMessage(Object^ parameter)
{
auto paraString = parameter->ToString();
auto formattedText = std::wstring(paraString->Data()).append(L"\r\n");
OutputDebugString(formattedText.c_str());
}
Usage:
LogMessage("Hello World!");
You could do this directly:
OutputDebugString(L"Hello World");
Notice the L in front of the string, to convert it directly to LPCWSTR.
Related
I am trying to call a shared library created with MathWorks MATLAB Compiler SDK from C# (.NET Core) running on a Linux container.
I have a matlab .m file that I've compiled into a .dll using the MATLAB R2018b compiler SDK. Because the final execution environment is .NET Core 2.2 running on a Linux container I chose the "C Shared Library" option. I call that shared library using the DLLImport mechanism of .NET.
Here is some code from my project. This code is KISS-level because I need to understand how to integrate MATLAB and C# on Linux before I start on the main project.
haveSomePi.m
function hal = haveSomePi()
hal = 3.1415;
end
MyMath.h
extern LIB_MyMath_C_API bool MW_CALL_CONV mlfHaveSomePi(int nargout, mxArray** hal);
MyMathWrapper.cs
[DllImport("MyMath.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void mlfHaveSomePi(int nargout, ref IntPtr hal);
MyMathWrapperTests.cs
[TestMethod]
public void ShouldReturnPi()
{
var hal = IntPtr.Zero;
MyMathWrapper.mlfHaveSomePi(1, ref hal);
double result = (double)hal;
Assert.AreEqual(3.1415, result, 1e-5);
}
The expected result is that the assert in the test method passes. It fails because trying to cast an IntPtr to a double doesn't make sense in this context. I'm sure there is a way to de-reference the IntPtr to get at the underlying double, I just haven't found that particular nugget of information.
I have been successful when compiling the .m file into a .NET library and into a COM object. I don't think I can use either of those libraries on Linux because of differences in the binary load/link format for each OS. When calling the method in the COM object I was able to directly cast the IntPtr to a double, there must be some marshaling magic going on in the background.
Is the method signature for the DLLImport statement correct? Do I map mxArray** to IntPtr?
How do I get the double from the IntPtr? Copy a block of memory into a managed byte array and cast?
My ultimate goal is to access a large signal processing library of matlab code from dotnet. The matlab code uses a lot of vectors and arrays so getting those into and out of the unmangaged library is my next hurdle.
Best regards.
I'm not a mathlab user, so I might be wrong, very wrong!
Getting Linux .dll equivalent
What you need, is the correct shared library/object for the run-time OS to be exported from mathlab.
Windows: .dll = Dynamic Link Library
Linux: .so = shared object [.net core butter and bread for Linux]
Instruction to get .so exported lib from mathlab
Compile your MATLAB files into a shared library (on UNIX)
mcc -t -L C -W MyMath-T link:lib haveSomePi.m libmmfile.mlib
Resulting MyMath.so, MyMath.exports, MyMath.h and MyMath.mlib, more details here
Binding Assembly
Make sure you have MyMath.so file next to MyMath.dll file, (bin, app data or where is needed)
Custom "NativeLibraryLoader" can be used to load different shared lib files based on OS, written by a GIT user because .net core din't had any (link). I would say is a bit over-complicated, but is your choice.
[DllImport] can be used instead!
DllImport without extension, supported on Windows and Linux and MAC will import the appropriate library for the target platform.
[DllImport("MyMath")]
Use <dllmap/> to map an import library name to the target platform library name. For MyMath.dll the corresponding Linux .so should be MyMath.so (more here)
[DllImport("MyMath.dll")]
Config map in csproj
<configuration>
<dllmap dll="MyMath.dll" target="MyMath.so" />
</configuration>
I think the main concern here is that you are doing
C Shared Library
Which is NOT C#...
Instead you should be doing
.NET Assembly
https://in.mathworks.com/help/compiler_sdk/gs/create-a-dotnet-application-with-matlab-code.html
It's important to note that .NET Core is not supported either, and you will have to change your project to a "classic" .NET Framework (If I recall correctly, at least 4.x)
I'm around trying to create an interoperable dll written in C # for use in Microsoft NAV 2016, for the development of a fiscal printer driver.
In my C # project I called to other functions dll (delivered by the company Bematech, in 32-bit and unmanaged).
Calls to the functions of the dll unmanaged (and tested from an .EXE) I make as follows:
[DllImport ( "BemaFi32.dll")]
public static extern int Bematech_FI_ProgramaAlicuota (Aliquot string, int ICMS_ISS);
When I try to run it from the NAV2016 I get the following error: .A call to "MyAssembly" failed with this message: You are trying to load a program with an incorrect format. Expection from HRESULT: 0x8007000B
I guess the error because the dll is not managed or 32-bit version (if that's the problem becomes more difficult because apparently there is no 64-bit version). Not how to solve the problem.
NAV cannot work with unmanaged code.
The only way is to write a wrapper dll which can be called from NAV.
Microsoft is doing the same with the Office SDK for example...
Cheers!
The problem was not the embedded dll unmanaged, was that the new dll to be 32 bit was not compatible with the client NAV, the solution was to change the 32bit client as follows:
Rename the file to Microsoft.Dynamics.Nav.Client.X64.exe Microsoft.Dynamics.Nav.Client.exe, and then a Microsoft.Dynamics.Nav.Client.X86.exe rename the file to Microsoft.Dynamics.Nav.Client. exe.
and the C / AL change in the variable declared the call to the dll
Property Value
Yes RunOnClient
I'am not a VC++ Dev but I'am searching to EDIT a source code. I want simply add new line on my Console with Different color (Green, Red ...)
void main()
{
static char * DES_KEY = "!_a^Rc*|#][Ych$~'(M _!d4aUo^%${T!~}h*&X%";
XStrDESUtil desUtil(DES_KEY);
printf("Password: %s\n", desUtil.Decrypt("1a6a2dfd3e44b8a0b02a2b66c801821e").c_str());
system("PAUSE");
}
I've searched but all what I found is
printf ("\033[34;01mBonjour\033[00m\n");
and those characters ... but it doesn't work for some reasons :(
Check out this header-only library that works for both, ANSI and Windows consoles:
https://github.com/tapio/rlutil
rlutil::setColor(rlutil::GREEN);
rlutil::setColor(rlutil::RED);
should suffice
In Windows, you can use the Windows Console Functions for this, such as SetConsoleTextAttribute.
I have created a small free C++ template library (one header only) to wrap many of that functionality. Available at http://cppconlib.codeplex.com/.
After building in Release mode, I am seeing exceptions which didn't occur in Debug mode. When debugging the release build, it looks like string references are not being passed correctly from the EXE (our application) to the DLL which is receiving the string reference.
Our EXE code looks like this:
string contents = "handle_message(): received=" + msg->encode();
LOG4CXX_DEBUG(logger, contents);
The LOG4CXX_DEBUG is going to log4cxx.dll, whose code looks like this:
CharMessageBuffer& CharMessageBuffer::operator<<(const std::basic_string<char>& msg) {
if (stream == 0) {
buf.append(msg);
} else {
*stream << msg;
}
return *this;
}
Looking at the Call Stack in the debugger, when I navigate down to the frame which has our source, I can see that contents is a valid string with size=583, capacity=838.
In the frame inside the log4cxx.dll (the next frame above in the stack) the string reference shows size=838, capacity=363113231 (and the values are all garbage).
Both our app and log4cxx.dll were compiled on the same machine, using the same runtime settings (/MD), but different versions of Visual Studio. The log4cxx dll was compiled using Visual Studio 2008 and our application was compiled using Visual Studio 2010. Running dumpbin on the 2 objects shows:
Our App (EXE)
MSVCP100.dll
MSVCR100.dll
log4cxx.dll (DLL)
MSVCP90.dll
MSVCR90.dll
Is this problem due to the fact that they are using different runtime versions?
If you pass non-POD (plain old datatypes) between DLL/EXE boundaries (like STL string or CRT FILE pointers) you must use the same shared CRT.
In your case, you must recompile all DLLs/LIBs with the same compiler!
See also: I can pass std::string for a Dll and what i can do with DLL´s?
The implicit question is:"Is there a way to pass data, hopefully using string and other STL containers, to DLLs of another version of visual studio either previous or later than the one that I'm using?".
Aside from using POD, there are probably three approaches: shared memory, sockets( to local host ) and MSMQ. All of these methods require additional extensive programming, but the deeper answer is found in how the interface is changing the input parameter.
I have found a possible solution to the string passing problem on the internet. It removes one layer of corruption; cast a pointer to the container to a uint and pass the uint. Dereference the uint to the pointer and the object is revealed. Beware, auto_ptrs are usually deleted in this process, so don't use them. If the passed object is still offset incorrectly( this happened to me with VS08 passing to a VS13 ), then pass the c_str() of the string instead. It's certainly inelegant, but we need to know all the alternatives. See "HowTo: Export C++ classes from a DLL" in Code Project( Nov 22, 2012 ).
I am trying libvips for visual studio 2012, starting with a simple example at
http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/vipsmanual/vipsmanualse1.html#x6-60001.1.1
#include <iostream>
#include <vips/vips>
int
main (int argc, char ⋆⋆argv)
{
if (argc != 3)
{
std::cerr << "usage: " << argv[0] << " infile outfile\n";
return (1);
}
try
{
vips::VImage fred (argv[1]);
fred.invert ().write (argv[2]);
}
catch (vips::VError e)
{
e.perror (argv[0]);
}
return (0);
}
What I did was:
Download and extract libvips at http://www.vips.ecs.soton.ac.uk/supported/7.34/win32/
Add to VC++ Directories->Include directories as vips-dev-7.34.1\include (vips-dev-7.34.1 is the extracted folder)
Add to VC++ Directories->Library directories as vips-dev-7.34.1\lib
Add a system path entry as vips-dev-7.34.1\bin
Basically because there are not much guide on using libvips with visual studio, so I applied the procedure that I used for OpenCV. The guide only say "All you need to do is include . This will get all of the include you need". Aparrently there are much more than that.
Upon building, the first error is "Unable to find header file "glib-object.h". Essentially, vips/vips call glib-objects "include which lies inside a subfolder of include \include\glib-2.0\glib-objects.h. I searched for a way to make VS search for all subfolders within the main include folder, it seems that such "recursive search" is not possible in VS. One has to point exactly to the folder containing header file and I may need to add all of the subfolders manually. So I tried adding vips-dev-7.34.1\include\glib-2.0 to VC++ Directories->Include directories. But then glib-objects.h calls for another glibconfig.h which is nowhere to be found within the include folder and subfolders.
Have someone sucessfully make libvips work with VS? Can you give me some advices if I miss something.
I'm the libvips maintainer. Sorry, it's very difficult to use the pre-built libvips binaries with VS, for various reasons (see below). I think your options are to use mingw instead, to cross-compile from linux (this is what I do), or to rebuild libvips yourself from source using VS (perhaps a week's work for an experienced dev?). There are some notes on the vips website about this issue.
The libvips.dll on the website has been cross-compiled from linux using mingw. It's set up for a linux-style build system with pkg-config, so you will have a lot of compiler flags to figure out in VS, and it's built against msvcrt.dll, the Windows C runtime, rather than msvcrtXX.dll, the VS runtime, so you will have endless annoying compatibility problems unless you also build against the Windows runtime.
Unfortunately VS no longer supports building against the Windows runtime. They have an internal tool which does support this mode, but it's not publicly available. I read somewhere you can coax the DDK compiler into doing this, but it's also not supported.
CoApp is an interesting project (partly supported by Microsoft) that is attempting to make building software on Windows less painful, but it's still in beta. You could maybe ask if they have a libvips packaged up for VS, or are considering making one.