Mixin string as argument from command line during compile time - d

Is there a way to get a string as a command line argument during compile time?
Example:
import std.stdio;
void main()
{
mixin(theString);
}
Ideal usage:
dmd app.d -theString="writeln("foo");

The only solution i found was using a bash script:
echo -n $1 > special_file
dmd source/app.d -J.
The program works as follows:
import std.stdio;
void main()
{
mixin(import("special_file"));
}
You can see it working at github

Related

QtCreator debug helpers "hello world"

I'm trying to get started using debug helpers in QtCreator.
But I can't even get anything simple to work.
I made this simple python file:
from dumper import *
def qdump_TestClass(d, value):
d.putNumChild(0)
d.putValue("hi")
Then add that file in here:
This is the C++ definition of the class:
struct TestClass {
int x, y;
};
I have been following the steps in this other question. But that didn't work for me.
Use double underscores in function name:
def qdump__TestClass(d, value):
^^
And, correct your path according to the documentation:
~/<Qt>/Tools/QtCreator/share/qtcreator/debugger/personaltypes.py
Use your Qt folder name (or path if it's not at ~).
The path showing in that dialog box is relative to your app.
Here's a complete working example:
main.cpp
struct TestClass
{
int x {12}, y {34};
};
int main()
{
TestClass t;
(void) t;
return 0;
}
personaltypes.py
from dumper import *
def qdump__TestClass(d, value):
d.putValue("TestClass")
d.putNumChild(2)
if d.isExpanded():
with Children(d):
d.putSubItem("x", value["x"])
d.putSubItem("y", value["y"])
Screenshot:

python, C, ctypes and a strange character

I'm trying to figure out how to use C functions in a python code. It looks like by far the simplest solution is to use ctypes. However for some reason I see strange behavior after I create a library which I import to python. All the details are provided below.
Here is what I have for C code:
/* mymodule.c */
#include <stdio.h>
#include "mymodule.h"
void displayargs(int i, char c, char* s) {
(void)printf("i = %d, c = %c, s = %s\n", i, c, s);
}
/* mymodule.h */
void displayargs(int i, char c, char* s)
I build a library out of it using the following commands:
gcc -Wall -fPIC -c mymodule.c
gcc -shared -Wl,-soname,libmymodule.so.1 -o libmymodule.so mymodule.o
My Python test code looks like this
#!/usr/bin/python
# mymoduletest.py
import ctypes
mylib = ctypes.CDLL('./libmymodule.so')
mylib.displayargs(10, 'c', "hello world!")
When I run ./mymoduletest.py I expect to see
i = 10, c = c, s = hello world!
however I see
i = 10, c = �, s = hello world!
Why � character is displayed instead of an actual char value of c?
Any help is appreciated.
You need to specify the function's argument and return types:
mylib.displayargs.argtypes = (ctypes.c_int, ctypes.c_char, ctypes.c_char_p)
mylib.displayargs.restype = None # None means void here.
If you don't specify the types, Python has to guess, and the guess it makes when you pass a string is that the function wants a char *.

How to import a class from a different source file in D?

I am new to the D language. I am attempting to import my custom class for use in the main() function.
Project struture:
DlangApp/app.d
DlangApp/ClassOne.d
ClassOne.d:
import std.stdio;
class ClassOne
{
string firstName;
string lastName;
this(string first, string last)
{
firstName = first;
lastName = last;
}
void writeName()
{
writefln("The name is: %s %s", firstName, lastName);
}
}
app.d:
import std.stdio;
import ClassOne;
void main()
{
auto aNumber = 10;
auto aString = "This is a string.";
writefln("A string: %s\nA number: %s", aString, aNumber);
}
When I run dmd -run app.d, I get this error message:
app.obj(app)
Error 42: Symbol Undefined _D8ClassOne12__ModuleInfoZ
---errorlevel 1
What am I doing wrong here?
Execute dmd -ofquakkels_app app.d ClassOne.d and, if the compilation was successfull, you will get the quakkels_app executable.
Or, if you really want to use the -run <file> [args...] parameter: dmd ClassOne.d -run app.d . Note that I put -run at the end - because after -run filename you may want to put some parameters that you want to pass to your application.
Now you probably understand why you got the compilation error above - simply DMD did not compile ClassOne.d file...
You can compile using rdmd. It is a wrapper around dmd with some additional functionality, but you can still pas dmd arguments. The main benefit is that you need to specify only one .d file - the one with main function. It understands import directives so it will include all necessary .d files

Calling SWIG generated code from Python interpreter

I am trying to use SWIG in an effort to call member functions of a C++ object from Python. Currently I have a small example class with a getter and setter to modify a member variable of the C++ class. Here is the C++ header file:
#ifndef _square_
#define _square_
#include <iostream>
class Square
{
private:
double x;
double y;
const char *name;
public:
void setName(const char*);
const char* getName();
Square() {
name = "construct value";
};
};
#endif
Here is the .cpp implementation file:
#include <iostream>
using namespace std;
#include "Square.h"
const char* Square::getName()
{
return name;
}
void Square::setName(const char* name)
{
this->name = name;
return;
}
And the Square.i file for SWIG:
%module Square
%{
#include "Square.h"
%}
%include "Square.h"
SWIG seems to generate the Square_wrap.cxx file without issue, and the resulting object files seem to link fine:
$ swig -python -c++ Square.i
$ g++ -c -fpic Square.cxx Square_wrap.cxx -I/usr/include/python2.7
$ g++ -shared Square.o Square_wrap.o -o _Square.so
Now for some example Python to test the results:
$ cat test2.py
#!/usr/bin/python
import Square
s = Square.Square()
print s.getName()
s.setName("newnametest")
print s.getName()
If I run this through the Python interpreter everything works fine:
$ python test2.py
construct value
newnametest
But if I interactively enter in the test lines via Python's CLI, things do not work:
$ python
Python 2.7.4 (default, Apr 19 2013, 18:28:01)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Square
>>>
>>> s = Square.Square()
>>>
>>> print s.getName()
construct value
>>> s.setName("newnametest")
>>> print s.getName()
>>> s.getName()
'<stdin>'
>>> s.setName('newnametest')
>>> s.getName()
''
>>> s.setName("newnametest")
>>> s.getName()
''
Does Python handle a Python script file differently under the hood in comparison to the CLI, or am I somehow abusing the Python interface generated by SWIG? Any tips on how to debug or understand the issue under the hood would be much appreciated.
As far as I see, you are just storing the reference on the cpp file (this->name = name). It would be good to copy it, because there are high chances the string doesn't last enough and is just discarded after the function returns (and garbage collected slightly after that). This would explain why in the script it works (there is no GCollection nor anything else happens between the two calls).
Try making a copy with strdup or using std::string.

Pass python list to c++ extension using boost python

I'm trying to write a c++ extension to replace the following python function in order to speed up my program
The python function looks like the following
def calc_dist(fea1, fea2):
#fea1 and fea2 are two lists with same length
...
I wrote the function using c++ and boost python like follows:
#include <vector>
#include <boost/python.hpp>
double calc_dist(vector<double>& fea1, vector<double>& fea2)
{
int len = fea1.size();
double s=0;
for(int i=0; i<len;i++){
double p=fea1[i];
double q=fea2[i];
...//calculating..
}
return s;
}
BOOST_PYTHON_MODULE(calc_dist)
{
using namespace boost::python;
def("calc_dist",calc_dist);
}
and compile the above cpp code into a .so file like
g++ calc_dist.cpp -shared -fPIC -o calc_dist.so -I /usr/include/python2.6 -lboost_python
and trying to use the .so in a python program, the import works fine, indicating the module can successfully imported.
However, whenever I pass two lists to the parameter to the function, python will give errors like
ArgumentError: Python argument types in
calc_dist.calc_dist(list, list)
did not match C++ signature:
calc_dist.calc_dist(std::vector<float, std::allocator<float> >,
std::vector<float, std::allocator<float> >)
can any one help me how to solve this problem? i.e pass a python list to c++ extension using boost?
Thanks a lot!
Why did you write a function accepting std::vector if you want it to operate on a Python list? They're different things.
Boost.Python exposes python lists as the list class.
So, your function should look something like
double calc_dist(boost::python::list fea1, boost::python::list fea2)
{
boost::python::ssize_t len = boost::python::len(fea1);
double s=0;
for(int i=0; i<len;i++){
double p = boost::python::extract<double>(fea1[i]);
double q = boost::python::extract<double>(fea2[i]);
...//calculating..
}
return s;
}
it's not tested, but hopefully is close enough to get you started ...