I'm studying Uniswapv2 codes and I got stucked with ABI. https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol
Why use ABI with call method, even if we can call transfer function from interface directly?
bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
.
.
.
function _safeTransfer(address token, address to, uint value) private {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
}
I've read a lot about ABI, and I'm confused about some says that it is JSON format and some says it is byte form. What is right?
You can use short form, like your example, without full ABI.
ABI for web3js is JSON form. Its used for simply call all existed functions and parameters. If you use many function and parameters -- JSON ABI much better for use.
You used short hacked version with selector - this is not good readable style of code.
1-
I believe token.call(abi.encodeWithSelector(SELECTOR, to, value)); token is another contract instance and called inside a contract. call is used to execute code of another contract
2-
The ABI encodes information about smart contracts' functions and events.
It acts as an interface between EVM-level bytecode and high-level smart
contract program code. To interact with a smart contract deployed on the
Ethereum blockchain, external programs require an ABI and the address
of the smart contract. The ABI consists of the following:
• All function names
• Input and output types of functions
• All event names and their parameters
Contract has hex representation and binary representation:
Contract.abi : This contains the ABI of the smart contract in JSON format.
Contract.bin : This contains the hex representation of binary of the smart contract code.
Related
As an example, a string that contains only a valid email address, as defined by some regex.
If a field of this type would be a part of a more complex data structure, or would be used as a function parameter, or used in any other context, the client code would be able to assume the field is a string containing a valid email address. Thus, no checks like "valid?" should be ever necessary, so approach of domaintypes would not work.
In Haskell this could be accomplished by a smart constructor (section 1.2) and in Java by ensuring the type is immutable (all setters private) and by adding a check in the constructor that throws a RuntimeException if the string used to create the type doesn't contain a valid email address.
If this is impossible in plain Clojure, I would like to see an example implementation in some well known extensions of the language, like Typed Clojure.
Ok, maybe, I understand now a question and I formulate in the comment my thoughts not really well. So I try to suggest an admissible solution to your question and then I try to explain some ideas I tried to tell in the comment.
1) There is a gen-class that generates compiled bytecode for a class and you can set constructor for the class there.
2) You can create a record with defrecord in some namespace that is private by convention in your project, then you
create another namespace with public api and define your factory function here. So the user of your public namespace will be able to call only public functions of your public namespace. (Of course, he can call also private ones, but with some another code)
3) You can just define a function like make-email that will return a map.
So you didn't specify your data structure anywhere.
4) You can just document your code where you will warn people to use the factory function for construction.
But! In Java if your code requires some interface, then it's user problem to give to your code the valid interface implementation. So if you write even a little bit general code in Java you already has lost the property of the valid email string. This stuff with interfaces is because Java is statically typed language.
Clojure is, in general, dynamically typed, so the user, in general, should be able to pass arbitrary data structure to arbitrary function without any type problems in compile time and it's his fault if he pass the wrong data. That makes, for example, this thing possible: You create a record and create a factory (constructor) function. And you expect a record to be passed in your code. But the user can pass a map with the same keys as your record fields names and the code will work.
So, in general, if you want the user of your code to be responsible for passing a required typed in dynamically typed language, then it cost nothing for user to be responsible for constructing it in a correct way that you provide to him.
Another solutions are: User just write tests. You can specify in your api functions :pre and :post conditions to check the structure. You can use typed clojure with the ideas I wrote above. And you can use some additional declarative libraries, like that was mentioned in the first comment of #Thumbnail.
P.S. I'm not a clojure professional, so I could easily miss some better solutions.
i'm using fmodex and i'm trying to use FMOD_FILE_OPEN_CALLBACK under C++.
FMOD_RESULT F_CALLBACK FMOD_FILE_OPEN_CALLBACK(const char *name, unsigned int *filesize, void **handle, void *userdata);
But I would like to execute a method of a class. So I thought to pass current object this as userdata of the callback and execute my callback method as it's proposed here.
But unlike Fmod Studio, there is no fileuserdata in FMOD_CREATESOUNDEXINFO, only userdata pointer.
And documentation says :
[w] Optional. Specify 0 to ignore. This is user data to be attached to
the sound during creation. Access via Sound::getUserData. Note: This
is not passed to FMOD_FILE_OPENCALLBACK, that is a different userdata
that is file specific.
But how can I access this file specific pointer ? Or there is an other solution to do that ?
Thanks.
was this solved yet? If not here's how i do it.
FMOD_CREATESOUNDEXINFO* info = new FMOD_CREATESOUNDEXINFO();
info->cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
// This is the field you want to set
info->fileuserdata = someUserData;
_system->createStream(file.c_str(), FMOD_DEFAULT, info, &_currentSound);
Are you using an old version of the fmod library? On my system the fileuserdata field does exist. I'm using the fmodex low level api that shipped with the fmod studio installation.
When the API in question does not provide a user data pointer for the callback, but does provide some kind of handle, as seems to be the case here, then you can forward each callback call to a C++ method (a non-static member function) in two general ways + 1 API-specific way:
use API functionality to associate a C++ object pointer with each handle, or
use a static storage std::map or std::unordered_map that associates each handle with a C++ object pointer, or
use a dynamically created trampoline function with the object address hardwired.
The third option was used e.g. in Borland's ObjectWindows framework in the 1990's, and it's generally the fastest, but it conflicts with current malware protection schemes, and since the C++ standard library doesn't support it (and as far as I know Boost doesn't support it either, although The Good Puppy over in the C++ Lounge here at SO once made a proposal about it), it's necessarily platform specific machine code.
Thus, if you don't know a way to do the first option I suggest you go with the second, a std::map or std::unordered_map that associates handles with C++ objects.
The main remaining technical hurdle is then to decide the proper time to create a map entry, and the proper time to remove it. That is highly dependent on the callback scheme. And unfortunately I have zero experience with yours, but maybe others can chime in about that detail.
Short Version
I'm using the entries from the vtable of a specific object to invoke virtual methods inherited from an interface.
In the end I'm searching for a way to get the exact offset each address to a virtual method has in the vtable of a specific object.
Detailed Version
Disclaimer
I know that this topic is implementation dependant and that one should not try to do this manually because the compiler does the (correct) work and a vtable is not considered to be a standard (let alone the dataformat).
I hereby testify that I already read dozens of "Don't do it... just, don't do it!"'s and am clear about the outrageous consequences my actions could have.
Therefore (and to favor a contructive discussion) I'll be using g++ (4.x.x) for the compiler on a Linux x64 Platform as my reference. Any software compiled using the below presented code will use the same setup, so it should be platform-indepandant as far as this is concerned.
Okay, this whole issue of mine is completely experimental, I don't want to use it in production code but to educate myself and my fellow students (my professor asked me if I could write a quick paper about this topic).
What I'm trying to do is basically the automatic invocation of methods using offsets to determine which method to invoke.
The basic outline of the classes is as follows (this is a simplification but shows the composition of my current attempts):
class IMethods
{
virtual double action1(double) = 0;
virtual double action2(double) = 0;
};
As you can see just a class with pure virtual methods which share the same signature.
enum Actions
{
actionID1,
actionID2
};
The enum-items are used to invoke the appropriate method.
class MethodProcessor : public IMethods
{
public:
double action1(double);
double action2(double);
};
Purposely omitted ctor/dtor of above class.
We can safely assume that these are the only virtual methods inherited from the interface and that polymorphy is of no concern.
This concludes the basic outline. Now to the real topic:
Is there a safely way to get the mapping of addresses in the vtable to the inherited virtual methods?
What I'm trying to do is something like this:
MethodProcessor proc;
size_t * vTable = *(size_t**) &proc;
double ret = ((double(*)(MethodProcessor*,double))vTable[actionID2])(&proc, 3.14159265359);
This is working out fine and is invoking action2, but I'm assuming that the address pointing to action2 is equal to index 1 and this part bugs me: What if there is some sort of offset added into the vtable before the address of action1 is defined?
In a book about the data object model of C++ I read that normally the first address in the vtable is leading to the RTTI (runtime type information), which in return I couldn't confirm because vTable[0] is legitimately pointing to action1.
The compiler knows the exact index of every virtual method pointer because, yeah, the compiler is building them and replacing every member invocation of the virtual methods with augmented code which equals the one I used above - but knows the index to use. I, for once, am taking the educated guess that there is no offset before my defined virtual methods.
Can't I use some C++-Hack to let the compiler compute the correct index on compile (or even run)-time? I could then use this information to add some offset to my enum-items and woulnd't have to worry about casting wrong addresses...
The ABI used by Linux is known: you should look at the section on virtual function table layout of the Itanium ABI. The document also specifies the object layout to find the vtable. I don't know if the approach you outlined works, however.
Note, that despite pointing at the document, I do not recommend to use the information to play tricks based on it! You unfortunately didn't explain what your actual goal is but it seems that using a pointer to member of the irtual functions is a more reliable approach to run-time dispatch to a virtual function:
double (IMethods::*method)(double)
= flag? &IMethods:: action1: &INethods::actions2;
MethodProcessor mp;
double rc = (mp.*method)(3.14);
I have nearly the same problem, even worse, in my case, this is for procuction code... don't ask me why (just tell me: "Don't do it... just, don't do it", or at least use an existing dynamic compiler such as LLC...).
Of course, this "torture" could be smoothed if compiler designers were asked to follow some generic C++ ABI specifications (or at least specify their own).
Apparently, there is a growing consensus on complying with "Generic C++ ABI" (also often called "ITANIUM C++ ABI", mentioned by Dietmar Kühl).
Because you are using G++ and because this is for educationnal purposes, I suggest you have a look at what the "-fdump-class-hierarchy" g++ switch does (you will find vtable layouts); this is what I personally use to be sure that I'm not casting wrong addresses.
Note: using a x86 (ia32) MinGW g++-4.7.2 compiler,
In double MethodProcessor::action( double ), the hidden "(MethodProcessor*)this" argument will be passed in a register (%ecx).
Whereas in ((double(*)(MethodProcessor*,double)), the first explicit "this" argument will be passed on stack.
I'm using SWIG to generate my JNI layer for a large set of C APIs and I was wondering what is the best practices for the below situations. The below not only pertain to SWIG but JNI in general.
When C functions return pointers to Structures, should the SWIG interface file (JNI logic) be heavily used or should C wrapper functions be created to return the data in pieces (i.e. a char array that contains the various data elements)?
When C Functions return void* should the C APIs be modified to return the actual data type, whether it be primitive or structure types?
I'm unsure if I want to add a mass amount of logic and create a middle layer (SWIG interface file/JNI logic). Thoughts?
My approach to this in the past has been to write as little code as possible to make it work. When I have to write code to make it work I write it in this order of preference:
Write as C or C++ in the original library - everyone can use this code, you don't have to write anything Java or SWIG specific (e.g. add more overloads in C++, add more versions of functions in C, use return types that SWIG knows about in them)
Write more of the target language - supply "glue" to bring some bits of the library together. In this case that would be Java.
It doesn't really matter if this is "pure" Java, outside of SWIG altogether, or as part of the SWIG interface file from my perspective. Users of the Java interface shouldn't be able to distinguish the two. You can use SWIG to help avoid repetition in a number of cases though.
Write some JNI through SWIG typemaps. This is ugly, error prone if you're not familiar with writing it, harder to maintain (arguably) and only useful to SWIG+Java. Using SWIG typemaps does at least mean you only write it once for every type you wrap.
The times I'd favour this over 2. is one or more of:
When it comes up a lot (saves repetitious coding)
I don't know the target language at all, in which case using the language's C API probably is easier than writing something in that language
The users will expect this
Or it just isn't possible to use the previous styles.
Basically these guidelines I suggested are trying to deliver functionality to as many users of the library as possible whilst minimising the amount of extra, target language specific code you have to write and reducing the complexity of it when you do have to write it.
For a specific case of sockaddr_in*:
Approach 1
The first thing I'd try and do is avoid wrapping anything more than a pointer to it. This is what swig does by default with the SWIGTYPE_p_sockaddr_in thing. You can use this "unknown" type in Java quite happily if all you do is pass it from one thing to another, store in containers/as a member etc., e.g.
public static void main(String[] argv) {
Module.takes_a_sockaddr(Module.returns_a_sockaddr());
}
If that doesn't do the job you could do something like write another function, in C:
const char * sockaddr2host(struct sockaddr_in *in); // Some code to get the host as a string
unsigned short sockaddr2port(struct sockaddr_in *in); // Some code to get the port
This isn't great in this case though - you've got some complexity to handle there with address families that I'd guess you'd rather avoid (that's why you're using sockaddr_in in the first place), but it's not Java specific, it's not obscure syntax and it all happens automatically for you besides that.
Approach 2
If that still isn't good enough then I'd start to think about writing a little bit of Java - you could expose a nicer interface by hiding the SWIGTYPE_p_sockaddr_in type as a private member of your own Java type, and wrapping the call to the function that returns it in some Java that constructs your type for you, e.g.
public class MyExtension {
private MyExtension() { }
private SWIGTYPE_p_sockaddr_in detail;
public static MyExtension native_call() {
MyExtension e = new MyExtension();
e.detail = Module.real_native_call();
return e;
}
public void some_call_that_takes_a_sockaddr() {
Module.real_call(detail);
}
}
No extra SWIG to write, no JNI to write. You could do this through SWIG using %pragma(modulecode) to make it all overloads on the actual Module SWIG generates - this feels more natural to the Java users probably (it doesn't look like a special case) and isn't really any more complex. The hardwork is being done by SWIG still, this just provides some polish that avoids repetitious coding on the Java side.
Approach 3
This would basically be the second part of my previous answer. It's nice because it looks and feels native to the Java users and the C library doesn't have to be modified either. In essence the typemap provides a clean-ish syntax for encapsulating the JNI calls for converting from what Java users expect to what C works with and neither side knows about the other side's outlook.
The downside though is that it is harder to maintain and really hard to debug. My experience has been that SWIG has a steep learning curve for things like this, but once you reach a point where it doesn't take too much effort to write typemaps like that the power they give you through re-use and encapsulation of the C type->Java type mapping is very useful and powerful.
If you're part of a team, but the only person who really understands the SWIG interface then that puts a big "what if you get hit by a bus?" factor on the project as a whole. (Probably quite good for making you unfirable though!)
Good day, masters. Suppose I have a java class A:
class A {
public A() {}
public native void setValue(String value);
public native String getValue();
}
When implementing the native C code, a global char[] variable is used to store the value just be set by native setValue method. The getValue method just return that global char[] variable.
Here comes my question: I create several A objects, and invoke their respective set/get method, I found that they end up writting and readding the same block of memory! Actually the global char[] variable in C native code is totally shared by all A object.
Can anybody give me some in-depth explaination of this behavior? I knew I had a fundmental misunderstanding in terms of the way JNI works. Thanks!
The problem is that you have the object oriented java on the one side, and the procedural C on the other side. When a java class A is loaded, JNI does not somehow create an object in the C world (this is C - not C++), there is no object-to-object mapping. So JNI loads the corresponding CPP file in the C world once into memory (this is completely normal behavior in C). The compiler sees a bunch of functions and a global reference, there is no need to create multiple instances somehow. When loading a Java class, all the JNI compiler does is to add the C file to the list of files to be compiled.
What you would like to have is a mapping between Java objects and C objects. This can be achieved in several ways, I suggest you read about the proxy pattern in JNI.
To explain very shortly, you have two fundamental ways to achieve this. You can either do it on the C side or on the Java side. When storing the relationship in the C world, you would maintain a hashtable in C where C objects map to Java objects. The other way around, you would have an int object in a Java object that is actually a pointer to a C object in memory. In the C code you would then dereference this pointer (through GetIntField()) and cast to the C object you require.
Of course adding
private String value;
to your Java class A, would indeed work very smootly. Java has a notion of objects, so you could access those Strings from the C world with
env->GetObjectField(obj, "value", "Ljava/lang/String;")
with env being the JNI environment.