Using C++/QtDBus.
I'm trying to get a reply from DBus call to function described as:
object, dict PullAll(string targetfile, dict filters).
I registered (qDBusRegisterMetaType) a type defined as: typedef QPair< QDBusObjectPath, QVariantMap > Transfer;
In QDBusPendingCallWatcher handler I'm doing:
QDBusPendingReply<Transfer> reply = *pwatcher;
I get an error:
Unexpected reply signature: got "oa{sv}", expected "(oa{sv})"
What's wrong? What is parentheses in "(oa{sv})"?
I think the whole message needs to be wrapped in a struct. At least you have the proper signature otherwise and are getting a response.
arrays: []
dict entries: {}
structs: ()
I'm not that familiar with QtDbus, but looking at the page for the QDbusArgument Class, you might have to do something like this:
argument.beginStructure();
argument << mystruct.objectpath << mystruct.array;
argument.endStructure();
Related
I'm trying to write a table test in go where the test cases will result in different errors. I then want to check if the type of the error matches a an error type defined in the test case, using errors.As(). Each test case is defined by a struct, so there needs to be a type in the struct that can hold any implementation of the interface error, which is then also to verify that the correct type was returned in the test.
I have tried defining the struct as follows
type testCase struct {
testInput string
expectedError error
}
I also have a number of custom errors that implement the error interface, lets say one is called myCustomError
I then declare a variable of that struct like this:
mTest := testCase{
testInput: "some failing string",
expectedError: myCustomError{},
}
if I then do the test like this...
err := someFunc(mTest.testInput)
if errors.As(err, &mTest.expectedError) {
// test have succeeded
}
... the if statement will always return true, regardless of which of my custom error types is returned.
I made a minimal example if this behavior on the Go Playground here: https://play.golang.org/p/uMdbMvfcdQi
In the playground example, I expect the string "matching myError1" to be printed twice, but instead it also matches myError2 when the value is stored as a plain error before it is used to check the type of the variable err.
Is is even possible to do something like this?
Store a pointer to the target value in the test case.
type testCase struct {
testInput string
expectedError interface{}
}
mTest := testCase{
testInput: "some failing string",
expectedError: &myCustomError{},
}
err := someFunc(mTest.testInput)
if errors.As(err, mTest.expectedError) {
// test have succeeded
}
Minimal example: https://play.golang.org/p/igJy9L_ui73
What is the best method for handling a Void type when it is returned by a function? The suggestions in http://docs.julialang.org/en/release-0.5/manual/faq/#how-does-null-or-nothingness-work-in-julia don't work.
A MWE (must be run from the REPL so Base.source_dir() returns Void):
julia> isempty(Base.source_dir())
ERROR: MethodError: no method matching start(::Void)
Closest candidates are:
start(::SimpleVector) at essentials.jl:170
start(::Base.MethodList) at reflection.jl:258
start(::IntSet) at intset.jl:184
...
in isempty(::Void) at ./iterator.jl:3
in isempty(::Void) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
julia> isdefined(Base.source_dir())
ERROR: TypeError: isdefined: expected Symbol, got Void
julia> typeof(Base.source_dir()) == Void
true
This is on Julia 0.5. The latter option works, but it's a bit ugly.
Void is a singleton -- a type with exactly one instance.
That one instance is Void() also called nothing.
Be aware that nothing === Void()
You can treat it just like any other value.
It is returned by a bunch of functions, like println.
You can check if something has returned nothing -- ie and instance of type Void.
By
julia> println()===nothing
true
For the sake of type-stability,
a method should not return nothing some of the time, and something some of the time.
in those case it should instead return a Nullable,
generally.
Let's assume I have this struct with a method:
package main
import (
"fmt"
"reflect"
)
type MyStruct struct {
}
func (a *MyStruct) AAction() {
fmt.Println("Hello a")
}
Now, if I want to call the method "AAction" by string, I can use reflection (this works):
func main() {
reflect.New(reflect.TypeOf(MyStruct{})).MethodByName("AAction").Call([]reflect.Value{})
}
The problem is, that I don't want to use MyStruct{} as an expression, but as a string. Of course this doesn't work:
func main() {
theStruct := "MyStruct"
theAction := "AAction"
reflect.New(reflect.TypeOf(theStruct)).MethodByName(theAction).Call([]reflect.Value{})
}
because reflect.Typeof(theStruct) would be a string.
I tried reading through the documentation, sadly, I can't find anything very useful.
I found this similar question: Call a Struct and its Method by name in Go?
Under the accepted question, the OP asks:
The issue in my case Is I cant not declare t is typed T, its must be some how I can declare t typed T by the name of T is string "T"
which gets answered by
[...] I would suggest to match the name against the string "T" somewhere in your code [...]
which doesn't solve the problem, as I would still need to call MyStruct{} somewhere.
The question is: is there any way to use a struct by giving the name as a string? (without manually mapping the the name of the struct to the struct)
Working version with using reflect.TypeOf(MyStruct{}):
PlayGround
Not working version, obviously calling the method on a string: PlayGround
Sorry, you can't. The answer is: you could not. There is no builtin or pre-initialized registry of type names.
To get started with reflection (reflect package), you need a value (of the type in question). Based on a string (string name of the type), you can't acquire a value of that type, so you can't get started.
If you do want to do what you want only by a string type name, you need to build your own "registry" prior to doing what you want.
As an exercise, I'm trying to create a wrapper for sqlite3. I've got the bridging header set up, and I can see the tool tips for the sqlite3 functions, but I can't figure out how to call sqlite3_open
sqlite3.h contains the following definitions of sqlite3 and sqlite3_open:
typedef struct sqlite3 sqlite3;
SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
Which means that sqlite3_open takes as a trailing parameter a pointer to a pointer to an anonymous structure, which seems clear enough in the tooltip:
func sqlite3_open(filename: CString, ppDb: CMutablePointer<COpaquePointer>) -> CInt
Knowing that CMutablePointer means to pass in &T, the closest I've come is:
class Database {
var handle:COpaquePointer
init(file:String) {
let error = sqlite3_open(file as CString, &handle)
}
deinit {
sqlite3_close(handle)
}
}
There's no error on the sqlite3_close line, so I think I'm at least close, but the sqlite3_open line yields:
Cannot convert the expression's type 'CInt' to type '$T9'
Any clues on how to do this?
Please, no answers that say to use FMDB or other Objective-C based interfaces. As I said, this is at least partially an exercise in figuring out how to use C libraries from swift.
The problem is not with the handle parameter, but with the string conversion. The following works…
class Database {
var handle: COpaquePointer = nil
init(file: NSString) {
let error = sqlite3_open(file.cStringUsingEncoding(NSUTF8StringEncoding), &handle)
}
}
I'm unsure as to why the 'as CString' doesn't work.
When you add #import <sqlite3.h> into Bridging-Header, the sqlite3 C/C++ API will be 'translated' into native swift function. So, the sqlite3_open will be like below.
func sqlite3_open(file:String, inout ppdb:COpaquePointer) -> Int
And you can call this function with "String" type parameter instead of "CString". The swift compiler will translate "String" into UTF8 String data stream automatically.
let error = sqlite3_open(filePath, &db)
So I'm currently writing code to access a player's uniqueNetId using:
Class'GameEngine'.static.GetOnlineSubsystem().UniqueNetIdToString(
OnlineSubsystemSteamworks(Class'GameEngine'.static.GetOnlineSubsystem()).LoggedInPlayerId.Uid);
But that leads to this:
Error, Call to 'UniqueNetIdToString', parameter 1: Const mismatch in Out variable
Does anybody have any idea what I'm doing wrong?
It's not actually a const mismatch. The function is expecting a struct and you are passing in a member of the struct instead. Try removing the .Uid, i.e.:
Class'GameEngine'.static.GetOnlineSubsystem().UniqueNetIdToString(
OnlineSubsystemSteamworks(Class'GameEngine'.static.GetOnlineSubsystem()).LoggedInPlayerId);