I have an array of data in a C++/CLI array that I can pass to a native function using pin_ptr<T>, no problem so far. Now, however, I need to pass the array on to a C++/STL function that expects a container such as std::array or std::vector.
The easy way of doing this (which I did first), is to copy element by element.
The second-easiest way is to call std::copy(), see the answer to this question: convert System::array to std::vector.
However, I want to skip the entire copying step and just use the pointer instead. Seeing as std::array requires a template argument to determine its length, I can't create one at runtime (but please do correct me if I'm wrong). Is there a way to create a vector or a different type of STL container, without unnecessary copying of data?
No it's not possible to do without copying, not with the standard containers anyway.
If you're still okay with copying then you should look at the std::vector constructor because I think the easiest way would be to do e.g.
std::vector<T>(your_pointer, your_pointer + number_of_elements)
If you definitely want to avoid copying, then it's not really that hard to write a simple wrapper around the pointer, including simple iterators needed for iteration (the reason it has to be a standard container I guess).
Just for fun and because I had some time over, I created just such a wrapper. It includes indexing and iterators. No bounds-checking.
See https://gist.github.com/pileon/c21cfba496e6c352dd81
Example program using it:
#include <iostream>
#include "pointer_container.h"
int main()
{
int a[20];
std::iota(a, a + 20, 0); // Initialize array
{
std::cout << "From array : ";
for (const auto item : a)
{
std::cout << item << ' ';
}
std::cout << '\n';
}
pointer_container<int> c(a, 20);
{
std::cout << "From container: ";
for (const auto item : c)
{
std::cout << item << ' ';
}
std::cout << '\n';
}
}
Expected output from the program:
From array : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
From container: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Since C++20 there is a way to use c++ containers with managed arrays in c++/cli that avoids copying the data: std::span
In c++20 it's possible to use std::span to wrap a managed c++/cli array. Then it can be used with standard container algorithms.
Unfortunately, Microsoft doesn't support c++/cli beyond c++17. Consequently one must first pass the pointer and length to a function in a different source file that is compiled using c++latest while compiling the caller's source file using the earlier c++17/cli. Fortunately the ABIs are compatible. This is easily set up for each file in the properties page of Visual Studio 2019.
Here's some sample code that creates a small managed array<double> then calls a function that wraps the managed data with std::span then sorts with std::sort
// file1.cpp compile with /cli
#include <iostream>
using namespace System;
void sortme(double *p, int len);
int main()
{
array<double>^ v = gcnew array<double> {1.0, 3.0, 2.0, 4.0};
pin_ptr<double> pin=&v[0];
int len=v->Length;
sortme(pin, len);
for (int i = 0; i < len; i++)
std::cout << v[i] << "\n"; // prints sorted array
}
// file2.cpp compile with c++latest
#include <span>
#include <algorithm>
void sortme(double *p, int len)
{
std::span data_clr(p, len);
std::sort(data_clr.begin(), data_clr.end());
}
Since std::array is just a wrapper you can cast a regular array to a pointer to a std::array. This isn't usable for other containers of course.
#include <array>
#include <iostream>
void test(std::array<int, 10>* pia)
{
std::cout << (*pia)[0] << std::endl;
}
int main()
{
int ix[10]{ 0 };
test((std::array<int, 10> *) ix);
}
Related
I am a beginner programmer. i have just started learning c++. I am currently trying to find project which will help me in practicing different types of loop and command statements. in my recent project of creating a program to find factorial for a given number using for loop i am having problems which might be due to code differences. Can you guys help me find the differences in each code and why the outputs of each program are different ?
this is a code i wrote myself :
#include <iostream>
using namespace std;
int main (){
int i,B;
// B=1;
for (i=0; i < 10; i++);
{
//B*=i;
cout << i;
//cout << B << endl;
}
}
the code above gives output of only 10
this is a code i copied
#include <iostream>
using namespace std;
int main(){
int a;
for (int a=1; a <=10;a++)
{
cout << a << endl ;
}
}
this gives output of all the numbers upto 10.
i cant see any reason why the first code would give me an output of 10 as it is "<10" and not "<=10
I'm tryin to create a few array-like structures for handeling MODBUS data & adressing.
I'm doing it within a structure so it's simpler later on to set certain values instead of referencing a datasheet to find out which address is coupled to the data.
Some addresses are left blank and are reserved for future use (I know this isn't specified in the MODBUS standard, the data shouldn't have to be exactly MODBUS specific).
I've created a struct which compiles on the software for the embedded device this should run on. However I wasn't quite sure it would run the way I imagined it, so I ran some test code on 2 different compiler. 1 being an online c-compiler which runs the way I excepected it to with just one warning at the reserved byte.
The 2nd one is ran within a visual studio c++ console application, which won't run cause it generates the error:
Error C2208 'unsigned short': no members defined using this type
This is the complete code which should run:
#include <stdio.h>
#include <stdint.h>
#define U16 uint16_t
#define UI unsigned int
struct t {
U16 t1;
union {
struct {
UI b_f1 : 2;
UI b_f2 : 2;
UI b_f3 : 2;
UI b_f4 : 2;
UI b_f5 : 2;
UI b_f6 : 2;
UI b_f7 : 2;
UI b_f8 : 2;
}f;
U16 c;
}t2;
U16; //Reserved space for later use <- this gives me the compiler error
U16 t3;
}test;
int main()
{
test.t3 = 12;
test.t2.f.b_f1 = 0; //0
test.t2.f.b_f2 = 2; //4 (8)
test.t2.f.b_f3 = 0; //16
test.t2.f.b_f4 = 0; //64
test.t2.f.b_f5 = 0; //256
test.t2.f.b_f6 = 0; //1024
test.t2.f.b_f7 = 2; //4096 (8192)
test.t2.f.b_f8 = 0; //16384
//tot: 8200
test.t1 = 3000;
int h; //test variable
for (int i = 0; i < (sizeof(test) / sizeof(U16)); i++) {
h = *(&test.t1 + (i*sizeof(U16));
printf("%d", h); //here I can now send every MODBUS address & data
}
return 0;
}
Setting the variables is not neccesarily needed, it's just for testing purposes
I excpected it will just generate a structure of 4 elements, one being a 0 pointer, that way the addressing is correct in a way that address 3 is not used and therefore 0 while address 4(t3) will contain more data.
Is there a way to make this work I planned to do, or should I just create some variables in between called Reserved1..Reserverd2..etc ?
A "declaration" like
U16; //Reserved space for later use
is simply not valid.
Just use some dummy name to solve your problem, like e.g.
U16 _reserved_; //Reserved space for later use
No you can't. A type on its own is not a valid declaration within a structure definition.
What you could do is use __LINE__ to help guarantee that the name you assign to the variable is unique:
#define _concat(a,b) a##b
#define concat(a,b) _concat(a,b)
and write
U16 concat(t, __LINE__);
which is unique insofar that the struct name t is unique.
Is there a way to make this work I planned to do?
No.
or should I just create some variables in between called Reserved1..Reserverd2..etc
Yes.
How can I pass an array between Erlang and an external C/C++ programs, assuming that the array is created and initialized by the Erlang program? ( I do not want to copy the whole array)?
P.S: I need a shared memory environment between C/C++ and Erlang
If by "array" you mean something that your C/C++ can easily access as an array, then you'll want to use an Erlang binary. These are easily handled in C/C++ code written as a NIF or driver. For example, given an Erlang function that takes a binary as an argument, you could implement it in C as a NIF as shown below:
#include <stdio.h>
#include "erl_nif.h"
static ERL_NIF_TERM
binfunc(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary bin;
unsigned i;
if (argc != 1 || !enif_inspect_binary(env, argv[0], &bin))
return enif_make_badarg(env);
printf("received binary of length %zu\r\ndata: ", bin.size);
for (i = 0; i < bin.size; ++i)
printf("%x ", bin.data[i]);
printf("\r\n");
return enif_make_atom(env, "ok");
}
static ErlNifFunc nif_funcs[] =
{
{"binfunc", 1, binfunc}
};
ERL_NIF_INIT(nif,nif_funcs,NULL,NULL,NULL,NULL)
The Erlang function would be implemented like this:
-module(nif).
-export([binfunc/1]).
-on_load(init/0).
init() ->
erlang:load_nif("./nif", 0).
binfunc(_Bin) ->
{error, "nif not loaded"}.
Running it would look like this:
Erlang/OTP 17 [RELEASE CANDIDATE 2] [erts-6.0] [source-f91fbb2] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.0 (abort with ^G)
1> nif:binfunc(<<"abcdef">>).
received binary of length 6
data: 61 62 63 64 65 66
ok
This implements just a simple array of chars, but using Erlang's powerful bit syntax you can easily implement structs, arrays, etc. that you can exchange between Erlang and C/C++.
So, I'm working at inventing my own tile map creation and I got a problem on size. The maximum size (which I did not set) is <700x700, anything higher makes it crash. First, I thought it's something I got wrong when making the "presentation version" which outputs the result on screen -> ScreenShot, but now I just finished making it more compact and tried using 800x800 and it still has the 7 limit, but I have no idea why. Since the code isn't that big I will show it here. If you have some tips I don't mind taking them.
#include <iostream>
#include <string.h>
#include <fstream>
#include <ctime>
#include <cstdlib>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#define _WIN32_WINNT 0x0501
#include <windows.h>
using namespace std;
int main()
{
sf::Vector2i Size;
int Points,rands,PointsCheck=1,x,y,RandX,RandY,CurrentNumber=1;
srand(time(0));
bool Done=false,Expanded,Border;
ofstream Out("txt.txt");
/***/
cout << "Size X-Y = "; cin >> Size.x >> Size.y;cout << endl;
cout << "MAX Points - " << (Size.x*Size.y)/10 << endl;
cout << "Number of POINTS = ";cin >> Points ;cout << endl;
/***/
int PixelMap[Size.x+1][Size.y+1];
/***/
for (x=1;x<=Size.x;x++) for (y=1;y<=Size.y;y++) PixelMap[x][y]=0;
/***/
while(PointsCheck<=Points)
{
rands=1+(rand()%10);
RandX=1+(rand()%(Size.x));RandY=1+(rand()%(Size.y));
if (rands==1 && PointsCheck<=Points && PixelMap[RandX][RandY]==0)
{PixelMap[RandX][RandY]=CurrentNumber;CurrentNumber+=2;PointsCheck++;}
}
/***/
while(Done==false)
{
Done=true;
for(x=1;x<=Size.x;x++)
for(y=1;y<=Size.y;y++)
if(PixelMap[x][y]%2!=0 && PixelMap[x][y]!=-1)
{
if (PixelMap[x+1][y]==0) PixelMap[x+1][y]=PixelMap[x][y]+1;
if (PixelMap[x-1][y]==0) PixelMap[x-1][y]=PixelMap[x][y]+1;
if (PixelMap[x][y+1]==0) PixelMap[x][y+1]=PixelMap[x][y]+1;
if (PixelMap[x][y-1]==0) PixelMap[x][y-1]=PixelMap[x][y]+1;
}
for(x=1;x<=Size.x;x++)
for(y=1;y<=Size.y;y++)
if(PixelMap[x][y]!=0 && PixelMap[x][y]%2==0) {PixelMap[x][y]--;Done=false;}
}
for(x=1;x<=Size.x;x++){
for(y=1;y<=Size.y;y++)
{Out << PixelMap[x][y] << " ";}Out << endl;}
//ShowWindow (GetConsoleWindow(), SW_HIDE);
}
What you have here is the concept from which this site gets its name. You have a stack overflow:
int PixelMap[Size.x+1][Size.y+1];
If you want to allocate a large amount of memory, you need to do it dynamically (on the heap).
You can do this any number of ways. Since you are using C++, I recommend using a std::vector. The only trick is making the array 2-dimensional. Usually this is done in the same way as the one you allocated on the stack, except you don't get language syntax to help you:
vector<int> PixelMap( (Size.x+1) * (Size.y+1) );
Above, you'll need to calculate the linear index from the row/column. Something like:
int someval = PixelMap[ row * (size.y+1) + column ];
If you really want to use the [row][column] indexing syntax, you can either make a vector-of-vectors (not recommended), or you can index your rows:
vector<int> PixelMapData( (Size.x+1) * (Size.y+1) );
vector<int*> PixelMap( Size.x+1 );
PixelMap[0] = &PixelMapData[0];
for( int i = 0; i < Size.x+1; i++ ) {
PixelMap[i+1] = PixelMap[i] + Size.y + 1;
}
Now you can index in 2D:
int someval = PixelMap[row][col];
There's a couple of problems with your code:
First off:
int PixelMap[Size.x+1][Size.y+1];
for (x=1;x<=Size.x;x++)
for (y=1;y<=Size.y;y++)
PixelMap[x][y]=0;
In the above snipped you are never setting the value of PixelMap[0][0], or PixelMap0, etc. Basically those values will be undefined. Arrays in C++ are 0 indexed so you need to be sure you address those. Also, why are you using Size.x+1 and Size.y+1? Something feels wrong about that.
A better loop would be:
int PixelMap[Size.x][Size.y];
for (x=0;x<Size.x;x++)
for (y=0;y<Size.y;y++)
PixelMap[x][y]=0;
Second, this next bit of code is illegible:
while(PointsCheck<=Points)
{
rands=1+(rand()%10);
RandX=1+(rand()%(Size.x));
RandY=1+(rand()%(Size.y));
if (rands==1 && PointsCheck<=Points && PixelMap[RandX][RandY]==0)
{
PixelMap[RandX][RandY]=CurrentNumber;
CurrentNumber+=2;
PointsCheck++;
}
}
You're only incrementing PointsCheck if
PointsCheck <= Points
Why? You test for this to be true in your while condition. PointsCheck doesn't get incremented anywhere before this test.
rands is never guaranteed to be equal to 1 by the way, so your loop could go on for eternity (though unlikely).
The next loop suffers from similar problems as above:
while(Done==false)
{
Done=true;
What's the reason for this? You never break out of the while loop, and you never set Done to false, so the next block of code will only ever be executed once. remove this bit.
Your for-loops that follow should start at 0 and go while < Size(Size.x and Size.y)
for(x=0;x<Size.x;x++)
for(y=0;y<Size.y;y++)
Fix these issues first, and then if you still have a problem we can move on. And for all our sake, please use brackets {} to scope your for loops and if statements so that we can follow. Also, separate commands onto separate lines. It's a lot of work for us to follow more than one semicolon per line.
EDIT
Since you seem unwilling to fix these issues first:
This could be an issue with the amount of memory allocated on the stack for your program. If you're trying to create an array of 800x800 integers, then you're using 800*800*4 bytes = 2.4 MB of data. I know this is higher than visual studio's default limit of 1 MB, but since a 700x700 array uses 1.8 MB, then whatever program you're using has a higher default (or you set visual studio's higher, but not high enough).
See if you can set your limit to at least 3 MB. More is better, though. If this doesn't fix your scaling problem up to 800, then you have other issues.
EDIT2
I just noticed this:
sf::Vector2i Size;
//unimportant stuff
cin >> Size.x >> Size.y;
int PixelMap[Size.x+1][Size.y+1];
Vector2i will probably have default values for x and y. If you want to dynamically allocate more than what those are, you cannot statically say
PixelMap[Size.x][Size.y]
You need to dynamically allocate the array. I strongly suggest using something like a std::vector > for this
e.g.(untested code):
sf::Vector2i Size;
//unimportant stuff
cin >> Size.x >> Size.y;
std::vector<vector<int> > PixelMap;
//Initialize values to 0
for(size_t i=0; i < Size.x; ++i){
vector<int> nextVec;
for(size_t j=0; j < Size.y; ++j){
nextVec.push_back(0);
}
PixelMap.push_back(nextVec);
}
Not sure if this has anything to do with your crash (I would have added a comment, but I don't have the reputation), but here's a problem I noticed:
Your array indexing scheme is not consistent. Since you're using index 1 to indicate the first element, your bounds checking should look like this...
if (y!=1 && y!=Size.y && x!=1 && x!=Size.x && ...
...instead of this...
if (y!=0 && y!=Size.y && x!=0 && x!=Size.x && ...
[EDIT]
I just tried this:
...
cout << "asdf" << endl;
int PixelMap[Size.x+1][Size.y+1];
cout << "asdf" << endl;
...
and verified it's a stack overflow problem. So, as others mentioned above, allocate your pixel map on the heap and it should be fine.
BTW, this code...
int PixelMap[Size.x+1][Size.y+1];
is not standard C++. It's an extension some compilers provide, called 'variable length arrays'. Check this out for more info -> Why aren't variable-length arrays part of the C++ standard?
[/EDIT]
This has been pending for a long time in my list now. In brief - I need to run mocked_dummy() in the place of dummy() ON RUN-TIME, without modifying factorial(). I do not care on the entry point of the software. I can add up any number of additional functions (but cannot modify code within /*---- do not modify ----*/).
Why do I need this?
To do unit tests of some legacy C modules. I know there are a lot of tools available around, but if run-time mocking is possible I can change my UT approach (add reusable components) make my life easier :).
Platform / Environment?
Linux, ARM, gcc.
Approach that I'm trying with?
I know GDB uses trap/illegal instructions for adding up breakpoints (gdb internals).
Make the code self modifiable.
Replace dummy() code segment with illegal instruction, and return as immediate next instruction.
Control transfers to trap handler.
Trap handler is a reusable function that reads from a unix domain socket.
Address of mocked_dummy() function is passed (read from map file).
Mock function executes.
There are problems going ahead from here. I also found the approach is tedious and requires good amount of coding, some in assembly too.
I also found, under gcc each function call can be hooked / instrumented, but again not very useful since the the function is intended to be mocked will anyway get executed.
Is there any other approach that I could use?
#include <stdio.h>
#include <stdlib.h>
void mocked_dummy(void)
{
printf("__%s__()\n",__func__);
}
/*---- do not modify ----*/
void dummy(void)
{
printf("__%s__()\n",__func__);
}
int factorial(int num)
{
int fact = 1;
printf("__%s__()\n",__func__);
while (num > 1)
{
fact *= num;
num--;
}
dummy();
return fact;
}
/*---- do not modify ----*/
int main(int argc, char * argv[])
{
int (*fp)(int) = atoi(argv[1]);
printf("fp = %x\n",fp);
printf("factorial of 5 is = %d\n",fp(5));
printf("factorial of 5 is = %d\n",factorial(5));
return 1;
}
test-dept is a relatively recent C unit testing framework that allows you to do runtime stubbing of functions. I found it very easy to use - here's an example from their docs:
void test_stringify_cannot_malloc_returns_sane_result() {
replace_function(&malloc, &always_failing_malloc);
char *h = stringify('h');
assert_string_equals("cannot_stringify", h);
}
Although the downloads section is a little out of date, it seems fairly actively developed - the author fixed an issue I had very promptly. You can get the latest version (which I've been using without issues) with:
svn checkout http://test-dept.googlecode.com/svn/trunk/ test-dept-read-only
the version there was last updated in Oct 2011.
However, since the stubbing is achieved using assembler, it may need some effort to get it to support ARM.
This is a question I've been trying to answer myself. I also have the requirement that I want the mocking method/tools to be done in the same language as my application. Unfortunately this cannot be done in C in a portable way, so I've resorted to what you might call a trampoline or detour. This falls under the "Make the code self modifiable." approach you mentioned above. This is were we change the actually bytes of a function at runtime to jump to our mock function.
#include <stdio.h>
#include <stdlib.h>
// Additional headers
#include <stdint.h> // for uint32_t
#include <sys/mman.h> // for mprotect
#include <errno.h> // for errno
void mocked_dummy(void)
{
printf("__%s__()\n",__func__);
}
/*---- do not modify ----*/
void dummy(void)
{
printf("__%s__()\n",__func__);
}
int factorial(int num)
{
int fact = 1;
printf("__%s__()\n",__func__);
while (num > 1)
{
fact *= num;
num--;
}
dummy();
return fact;
}
/*---- do not modify ----*/
typedef void (*dummy_fun)(void);
void set_run_mock()
{
dummy_fun run_ptr, mock_ptr;
uint32_t off;
unsigned char * ptr, * pg;
run_ptr = dummy;
mock_ptr = mocked_dummy;
if (run_ptr > mock_ptr) {
off = run_ptr - mock_ptr;
off = -off - 5;
}
else {
off = mock_ptr - run_ptr - 5;
}
ptr = (unsigned char *)run_ptr;
pg = (unsigned char *)(ptr - ((size_t)ptr % 4096));
if (mprotect(pg, 5, PROT_READ | PROT_WRITE | PROT_EXEC)) {
perror("Couldn't mprotect");
exit(errno);
}
ptr[0] = 0xE9; //x86 JMP rel32
ptr[1] = off & 0x000000FF;
ptr[2] = (off & 0x0000FF00) >> 8;
ptr[3] = (off & 0x00FF0000) >> 16;
ptr[4] = (off & 0xFF000000) >> 24;
}
int main(int argc, char * argv[])
{
// Run for realz
factorial(5);
// Set jmp
set_run_mock();
// Run the mock dummy
factorial(5);
return 0;
}
Portability explanation...
mprotect() - This changes the memory page access permissions so that we can actually write to memory that holds the function code. This isn't very portable, and in a WINAPI env, you may need to use VirtualProtect() instead.
The memory parameter for mprotect is aligned to the previous 4k page, this also can change from system to system, 4k is appropriate for vanilla linux kernel.
The method that we use to jmp to the mock function is to actually put down our own opcodes, this is probably the biggest issue with portability because the opcode I've used will only work on a little endian x86 (most desktops). So this would need to be updated for each arch you plan to run on (which could be semi-easy to deal with in CPP macros.)
The function itself has to be at least five bytes. The is usually the case because every function normally has at least 5 bytes in its prologue and epilogue.
Potential Improvements...
The set_mock_run() call could easily be setup to accept parameters for reuse. Also, you could save the five overwritten bytes from the original function to restore later in the code if you desire.
I'm unable to test, but I've read that in ARM... you'd do similar but you can jump to an address (not an offset) with the branch opcode... which for an unconditional branch you'd have the first bytes be 0xEA and the next 3 bytes are the address.
Chenz
An approach that I have used in the past that has worked well is the following.
For each C module, publish an 'interface' that other modules can use. These interfaces are structs that contain function pointers.
struct Module1
{
int (*getTemperature)(void);
int (*setKp)(int Kp);
}
During initialization, each module initializes these function pointers with its implementation functions.
When you write the module tests, you can dynamically changes these function pointers to its mock implementations and after testing, restore the original implementation.
Example:
void mocked_dummy(void)
{
printf("__%s__()\n",__func__);
}
/*---- do not modify ----*/
void dummyFn(void)
{
printf("__%s__()\n",__func__);
}
static void (*dummy)(void) = dummyFn;
int factorial(int num)
{
int fact = 1;
printf("__%s__()\n",__func__);
while (num > 1)
{
fact *= num;
num--;
}
dummy();
return fact;
}
/*---- do not modify ----*/
int main(int argc, char * argv[])
{
void (*oldDummy) = dummy;
/* with the original dummy function */
printf("factorial of 5 is = %d\n",factorial(5));
/* with the mocked dummy */
oldDummy = dummy; /* save the old dummy */
dummy = mocked_dummy; /* put in the mocked dummy */
printf("factorial of 5 is = %d\n",factorial(5));
dummy = oldDummy; /* restore the old dummy */
return 1;
}
You can replace every function by the use of LD_PRELOAD. You have to create a shared library, which gets loaded by LD_PRELOAD. This is a standard function used to turn programs without support for SOCKS into SOCKS aware programs. Here is a tutorial which explains it.