I'm looking for a way to iterate over Tcl array, specified by it's name in C code.
The problem for which this iteration is needed is a SWIG typemap to convert Tcl array to C++ map. The code should look like this:
%typemap(tcl8, in) map<int,int> * (map<int,int> dltmp) {
map<int,int> *cMap = new map<int,int>;
int key, value;
pair<int,int> mapEnt;
// somehow iterate over Tcl array specified by it's name in $source
// to get key and value
{
mapEnt.first = key;
mapEnt.second = value;
cMap.insert(mapEnt);
}
$target = cMap;
}
Related
I am trying to learn Kotlin/Native C interop
I exported some Kotlin classes as C dynamic Lib and succeeded in access methods with primitive return types
But When trying to access class members in a instance object which returned by a method, the object contains something named as pinned
Code sample:
#Serializable
data class Persons (
val results: Array<Result>,
val info: Info
)
class RandomUserApiJS {
fun getPersonsDirect() : Persons {
return runBlocking {
RandomUserApi().getPersons()
}
}
}
Now when using them in C codeblocks,
In this image, note that the persons obj only showing a field named pinned and no other member functions found.
Since I don't know that much in C/C++ and can't investigate further.
Please help me to understand to access instance members of Kotlin Class in exported C lib?
Header file for ref:
https://gist.github.com/RageshAntony/a0b9007376084fa8b213b022b58f9886
for your gist
https://gist.github.com/RageshAntony/a0b9007376084fa8b213b022b58f9886
I modified the following:
// I comment this annotation
// #Serializable
data class Persons(
val results: List<Result>,
val info: Info,
/**
* the Result's properties too many
* I will use a simple data class for this example
* how to get c array from Persons (also suitable any iterable)
*/
val testList: List<Simple>,
) {
public fun toJson() = Json.encodeToString(this)
companion object {
public fun fromJson(json: String) = Json.decodeFromString<Persons>(json)
}
val arena = Arena()
fun getTestListForC(size: CPointer<IntVar>): CPointer<COpaquePointerVar> {
size.pointed.value = testList.size
return arena.allocArray<COpaquePointerVar>(testList.size) {
this.value = StableRef.create(testList[it]).asCPointer()
}
}
fun free() {
arena.clear()
}
}
/**
* kotlin <-> c bridge is primitive type
* like int <-> Int
* like char* <-> String
* so the Simple class has two primitive properties
*/
data class Simple(
val name: String,
val age: Int,
)
#include <stdio.h>
#include "libnative_api.h"
int main(int argc, char **argv) {
libnative_ExportedSymbols* lib = libnative_symbols();
libnative_kref_MathNative mn = lib->kotlin.root.MathNative.MathNative();
const char *a = lib->kotlin.root.MathNative.mul(mn,5,6); // working
printf ("Math Resullt %s\n",a);
libnative_kref_RandomUserApiJS pr = lib->kotlin.root.RandomUserApiJS.RandomUserApiJS();
libnative_kref_Persons persons = lib->kotlin.root.RandomUserApiJS.getPersonsDirect(pr);
// when accessing above persons obj, only a field 'pinned' availabe, nothing else
int size;
libnative_kref_Simple* list = (libnative_kref_Simple *)lib->kotlin.root.Persons.getTestListForC(persons, &size);
printf("size = %d\n", size);
for (int i = 0; i < size; ++i) {
const char *name = lib->kotlin.root.Simple.get_name(list[i]);
int age = lib->kotlin.root.Simple.get_age(list[i]);
printf("%s\t%d\n", name, age);
}
lib->kotlin.root.Persons.free(persons);
return 0;
}
// for output
Math Resullt The answer is 30
size = 3
name1 1
name2 2
name3 3
But I don't think calling kotlin lib through C is a good behavior, because kotlin native is not focused on improving performance for now, in my opinion, all functions that can be implemented with kotlin native can find solutions implemented in pure c, So I'm more focused on how to access the c lib from kotlin. Of course, it's a good solution if you absolutely need to access klib from c, but I'm still not very satisfied with it, then I may create a github template to better solve kotlin-interop from c.But that's not the point of this answer.
Alright, so I got a private ?Vector $lines which is empty when constructing the object and now I want to add strings to that Vector. The following Hack code works well:
<?hh
class LineList {
private ?Vector<string> $lines;
public function addLine(string $line): void {
$this->file[] = trim($line);
}
}
But when checking the code with hh_client, it gives me the following warning:
$this->file[]]: a nullable type does not allow array append (Typing[4006])
[private ?Vector<string> $lines]: You might want to check this out
Question: How do I add elements to the Vector without that the checker pushs this warning?
The easiest way would be to not use a nullable Vector. private Vector<string> $lines = Vector {}; gets around the need for a constructor too.
Otherwise, you'll need to check if the value isn't null, then append to it:
public function addLine(string $line): void {
$vec = $this->lines;
if ($vec !== null) $vec[] = trim($line);
}
You can't just check if $this->lines !== null as it is possible for it to change value between checking and appending (with something like a tick function), hence why it is assigned to a local variable instead.
I need to create a Map like data structure using an Array or ArrayLists.
Quick program over view: My map holds objects of Word which is a string and holds a frequency count of how many times the word appears in a next file.
Here is code for MyMap, Program outputs nothing.
List<Word>[] table;
int tableSize;
int index;
public MyMap(int tableSize){
table = new ArrayList[tableSize];
this.tableSize = tableSize;
}
//Problem!!
public void put(Word w){
index = Math.abs(w.hashCode()) % tableSize;
if(table[index].isEmpty()){
table[index].add(w);
}
else{
w.increaseFreq();
table[index].set(index, w);
}
}
public void displayMap(){
for(List<Word> w: table){
System.out.println(w);
}
}
}
How about using either a Generic.Dictionary<string,Word> or a KeyedCollection<string,Word>?
If you use the KeyedCollection then you will need to inherit from it and provide a GetKeyForItem implementation.
Hi everybody and thanks for your time,
I read filenames in a QList. This is what I've done:
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFiles);
dialog.setViewMode(QFileDialog::Detail);
if(dialog.exec()) {
files.append(dialog.selectedFiles());
}
foreach(QString file, files) {
// add files to a table
}
I have all files in the QList files. Now I want the user to add information to this list. In PHP (or javascript) I would do something like this:
$fileinformation = array();
foreach($files AS $file) {
array_push($fileinformation, array (
'filename' => $file,
'doAction1' => false,
'doAction2' => true,
'parameter2' => array (
'value1' => $val1,
'value2' => $val2
)
)
)
}
And in the next step, I would make it possible for the user to edit the default options by editing $fileinformation['parameter2']['value']. But how can I do this in QT? I know, there are certain functions in qt like QList and QMap but both are not multidimensional and too unflexible for this case.
What did I miss?
You haven't missed anything. In a statically-typed language, you generally do not have objects of a completely different type all in the same container.
Assuming all of the parameters are defined at compile time, you can define a class or struct that contains those parameters and store it in a list. For brevity, I'm using a raw struct in this example. You may wish to explicitly initialize its members with a constructor and possibly wrap its data into a meaningful class.
struct FileInformation
{
QString filename;
bool doAction1;
bool doAction2;
struct ParameterStruct
{
QString value1; // I'm guessing it's QString, since you don't show what type it was.
QString value2;
} parameter2;
};
int main()
{
QList<FileInformation> myList;
FileInformation info;
info.fileName = "filename.txt";
info.doAction1 = false;
info.doAction2 = true;
info.parameter2.value1 = "someValue";
info.parameter2.value2 = "someOtherValue";
myList.append(info);
//now to change stuff!
myList[0].parameter2.value1 = "a new value";
}
It is possible to do this more akin to your example above (by nesting QVariantMaps), but that would be quite ugly, as C++'s static typing would demand manually casting at every access.
I have this c++11 code:
auto gen = []() -> double { /* do stuff */ };
std::generate(myArray.begin(), myArray.end(), gen);
How would I do the same with D's array? std.algorithm.fill doesn't take a function object, and I don't know how to pass a function to recurrence.
Here's a version that seems to work:
import std.algorithm, std.array, std.range, std.stdio;
void main() {
writefln("%s", __VERSION__);
int i;
auto dg = delegate float(int) { return i++; };
float[] res = array(map!dg(iota(0, 10)));
float[] res2 = new float[10];
fill(res2, map!dg(iota(0, res2.length)));
writefln("meep");
writefln("%s", res);
writefln("%s", res2);
}
[edit] Added fill-based version (res2).
I tested it in Ideone (http://www.ideone.com/DFK5A) but it crashes .. a friend with a current version of DMD says it works though, so I assume Ideone's DMD is just outdated by about ten to twenty versions.
You could do something like
auto arr = {/* generate an array and return that array */}();
If it's assigned to a global it should be evaluated at compile-time.
You can also use string mixins to generate code for an array literal.