Is there a functional equivalent for the C# function .tostring("X4"), to C++?
I've been scratching my head for a few days wondering why my sensor is reporting a different serial number to what the manufacturer software (written in C#) and what my C++ code reports. The serial number is also written on the sensor, which ties in with what the manufacturer C# code reports. On inspection of their source code, they're using the .tostring("X4") function to convert it to "human readable", which makes sense (from a "oh thats why it's different", not a "why on earth would you do that" point of view).
For further info - https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings
A similar question but C# to Java - C# .ToString("X4") equivalent in Java
There's is no readily available equivalent function in C++, but you could create one that works in a similar way:
#include <iostream>
#include <sstream>
#include <string>
template<class T>
std::string tostringX(unsigned len, T v) {
std::ostringstream os;
os << std::hex << v;
auto rv = os.str();
if(rv.size() < len) rv = std::string(len - rv.size(), '0') + rv;
return rv;
}
int main() {
std::cout << tostringX(4, 0xFEDC) << '\n'; // outputs "fedc"
}
#include <iostream>
#include<sstream>
#include <iomanip>
int main() {
int x = 12;
std::stringstream stream;
stream << std::setfill('0') << std::setw(4)<< std::hex << x;
std::cout << stream.str();
}
Output : 000c
I guess that's the answer you're looking for.
Related
I am trying to call a C# lib from a C++ program. C# and this interop is pretty new for me. Some of the communications have been easy until I had to face strings inside structures. I have been reading a lot and saw several examples, but I am unable to replicate them and make them work.
I extracted the code with the example of sending a string, and retriving the string which works (_string_exchange). And the method _return_struct which returns a struct with a string that doesnt works. Debugger fails when I try to use the variable for std::cout, with an unhandled exception from 0x00007FFFEA98A388 (KernelBase.dll). The Console.WriteLine havent wrote anything during the call.
I assume this is a problem matching the scrutures. Both are compiled in release x64, using .NET Framework 4.6.1. Also I have been checking with sizeof() and Marshal.SizeOf() to check that both have the same byte length. Also tried to change c++ project character from unicode to multibyte without success.
I saw examples like this that were pretty good explaning everything, but I dont know what I am missing: Passing strings/arrays within structures between C++/C#
C++ program:
struct myStruct
{
int myInt;
double myDouble;
bool myBool;
char myString[64];
};
int main() {
const TCHAR* pemodule = _T("F:\\PATH\\TO\\DLLsi\\LibCSharp.dll");
HMODULE lib = LoadLibrary(pemodule);
typedef LPCSTR(_cdecl *_string_exchange)(LPCSTR s);
auto pString_exchange = (_string_exchange)GetProcAddress(lib, "_string_exchange");
LPCSTR test = pString_exchange("LPCSTR test works fine");
std::cout << test << std::endl;
typedef myStruct(_cdecl *_return_struct)();
auto pReturn_struct = (_return_struct)GetProcAddress(lib, "_return_struct");
myStruct aStruct = pReturn_struct();
std::cout << aStruct.myString << aStruct.myBool << " " << aStruct.myDouble << " " << aStruct.myInt << std::endl;
return 0;
}
C# library:
namespace LibCSharp
{
public class Class1
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct myStruct
{
public int myInt;
public double myDouble;
[MarshalAs(UnmanagedType.U1)]
public byte myBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string myString;
}
[DllExport]
public static myStruct _return_struct()
{
Console.WriteLine("test");
myStruct a;
a.myInt = 3;
a.myDouble = 2;
a.myBool = 1;
Console.WriteLine(a.myBool);
a.myString = "Hello world! My values are: ";//28
Console.WriteLine(a.myString);
return a;
}
[DllExport]
public static string _string_exchange(string s)
{
Console.WriteLine(s);
return s;
}
}
}
I am also aiming in a future to make this structure an array, I hope once this is solved I wont face much problems, but any comment in advance is also wellcome.
Thank you in advance
Maybe you should try using Named Pipes to communicate between two processes. It allows you to open stream and transfer any byte arrays. So you can serialize any object to array and transfer it.
Here's working solution for C++ and C# communication.
Pipes are more flexible and system-independent than interop. But probably less efficient...
At first glance, it appears your c# code is marshaling that return string as a tchar[64] which is almost certainly a unicode wchar[64]; while your C++ code is expecting an ascii char[64] to be there.
Try changing the c++ definition to
struct myStruct
{
int myInt;
double myDouble;
bool myBool;
TCHAR myString[64];
};
Is there a way in C# to extend a function like following ?
void foo()
{
// function body, instructions
return;
}
and then somewhere else in the code
foo += (x) => { // some functionality }
Which in practice would add the lambda functionality to be fired at the end of a foo() execution.
What would be the name and the internal details of such mechanism ?
Is something of this nature possible in C++?
Your example won't compile with the message :
error CS1656: Cannot assign to 'foo' because it is a 'method group'
It's not possible to do stuff like that. What you saw was probably operator += for events. Here's an example with a lambda.
Regarding C++
It's not possible to add a call to the end of a different function (the same as for C#). But you can implement events and overload operator += for your events to accept pointers to functions.
It is just a possibility just to show you that a one minute trial can give you an insight. But as Kirill Daybov mentioned in one of his comment I would encourage you to google delegate c++, you will find articles with much stronger technical hints
#include <iostream>
#include <list>
#include <functional> //c++11
using namespace std;
//For exercice only, C++11 required
template<typename U> class naive_delegate
{
list<function<void(U)>>_list;
public:
naive_delegate<U> & operator+= (function<void(U)> && fref)
{ _list.push_back(fref); return *this;}
void operator()(U && input_param)
{
if (_list.empty() )
cout << "Nothing to do for call of delegate with param " << input_param << endl;
else
for ( const auto & elem : _list)
elem(input_param);
}
};
void anwser(int i) { cout << "The answer is " << i << endl; }
int main()
{
naive_delegate<int> ndel;
ndel(1);
ndel += [](int i) { cout << "What is the answer ? " << endl; };
ndel += anwser;
ndel(42);
return 0;
}
The results are
Nothing to do for call of delegate with param 1
What is the answer ?
The answer is 42
Note that among others, I am not able to treat removal (-=) ...
I am trying to invoke a simple C# class method from C, using embedded mono (as described here). I can invoke the method, but the C# function receives 0 as the argument, instead of the number I pass in. The C# function returns a result and the C code is seeing the correct result - I just can't pass arguments in. What am I doing wrong?
The C# assembly (MonoSide.cs) is:
using System;
public class MainEntryPoint
{
static public void Main(string[] args)
{
}
}
namespace Fibonacci
{
public class Fibonacci
{
public long FibonacciNumber(long entryNumber)
{
Console.Write(string.Format("(inside C#) FibonacciNumber({0})", entryNumber));
var sqrt5 = Math.Sqrt(5);
var phi = (1 + sqrt5) / 2;
var exp = Math.Pow(phi, entryNumber);
var sign = ((entryNumber & 1) == 0) ? -1 : 1;
var entry = (exp + sign / exp) / sqrt5;
Console.WriteLine(string.Format(" = {0}.", entry));
return (long) entry;
}
}
}
Here is the C code:
#include <stdio.h>
#include <stdlib.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
int main(int argc, char **argv)
{
long long entryNumber = (argc > 1) ? atoi(argv[1]) : 10;
// For brevity, null checks after each mono call are omitted.
MonoDomain *domain = mono_jit_init("MainEntryPoint");
MonoAssembly *monoAssembly = mono_domain_assembly_open(domain, "MonoSide.exe");
char *monoArgs[] = {"Mono"};
mono_jit_exec (domain, monoAssembly, 1, monoArgs);
MonoImage * monoImage = mono_assembly_get_image (monoAssembly);
MonoClass * monoClass = mono_class_from_name (monoImage, "Fibonacci", "Fibonacci");
MonoMethod *monoMethod = mono_class_get_method_from_name(monoClass, "FibonacciNumber", 1);
// Invoking method via thunk.
typedef long long (*FibonacciNumber) (long long *);
FibonacciNumber fibonacciNumber = mono_method_get_unmanaged_thunk (monoMethod);
printf("Calling C# thunk function FibonacciNumber(%I64u)...\n", entryNumber);
long long number = fibonacciNumber(&entryNumber);
printf("Fibonacci number %I64u = %I64u\n", entryNumber, number);
mono_jit_cleanup (domain);
return 0;
}
I am compiling it with Dev-Cpp using this makefile:
test.exe: CSide.c MonoSide.exe
gcc CSide.c -o test.exe -m32 -mms-bitfields -IC:/Progra~2/Mono/Include/mono-2.0 -LC:/Progra~2/Mono/lib -L/Embedded -lmono-2.0 -lmono
MonoSide.exe: MonoSide.cs
mcs MonoSide.cs
The output is:
Calling C# thunk function FibonacciNumber(10)...
(inside C#) FibonacciNumber(0) = 0.
Fibonacci number 10 = 0
(Why these functions? This is just a sample, can-I-get-this-to-work program and not my final goal.)
Edit:
It works if I pass the function argument as a pointer in the C code. The C# receives it correctly. The above code has been modified from:
typedef long long (*FibonacciNumber) (long long);
...
long long number = fibonacciNumber(entryNumber);
to:
typedef long long (*FibonacciNumber) (long long *);
...
long long number = fibonacciNumber(&entryNumber);
To me, this means that the safest way to pass anything more complicated between C and C# is via buffers, with matching serializers and deserializers in C and C#.
It works if I pass the function argument as a pointer in the C code. The C# receives it correctly. The above code has been modified from:
typedef long long (*FibonacciNumber) (long long);
...
long long number = fibonacciNumber(entryNumber);
to:
typedef long long (*FibonacciNumber) (long long *);
...
long long number = fibonacciNumber(&entryNumber);
To me, this means that the safest way to pass anything more complicated between C and C# is via buffers, with matching serializers and deserializers in C and C#.
In C#:
public sealed class StateMachine<TState, TTrigger>
I'd like to write a C++ equivalent.
Like this:
template <typename TState, typename TTrigger>
class StateMachine
{
//...
};
This site has a pretty good explanation of how to make template classes. Example:
// function template
#include <iostream>
using namespace std;
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax<int>(i,j);
n=GetMax<long>(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
Use this in combination with this previous Stack Overflow question to achieve the sealed aspect of the class.
You could use what Stuart and Xeo proposed, and if you want to make the class sealed here is link that explains how to do it.
EDITED: this is even better.
How would you go about converting the following C #define into c#.
#define get16bits(d) (*((const uint16_t *) (d)))
#if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]) )
#endif
I know you probably replace the uint32_t which with UInt32 change the other types to c# equivalent, but how proceed from making the above a static method. Would that be the best way of going about it.
Bob.
I do not know why you are checking to see if get16bits is defined immediately after you define it, as the only way it would not be is a preprocessor error which would stop your compile.
Now, that said, here's how you translate that godawful macro to C#:
aNumber & 0xFFFF;
In fact, here's how you translate that macro to C:
a_number & 0xFFFF;
You don't need all this casting wizardry just to get the lower 16 bits of a number. Here's more C defines to show you what I'm talking about:
#define getbyte(d) (d & 0xFF)
#define getword(d) (d & 0xFFFF)
#define getdword(d) (d & 0xFFFFFFFF)
#define gethighword(d) ((d & 0xFFFF0000) >> 16)
#define gethighbyte(d) ((d & 0xFF00) >> 8)
Have you really used that macro in production code?
Getting the lower 16 bits of an integer is quite easy in C#:
int x = 0x12345678;
short y = (short)x; // gets 0x5678
If you want a static method for doing it, it's just as simple:
public static short Get16Bits(int value) {
return (short)value;
}