Current situation & context
For a school assignment, we have to write our own programming language. Currently, I am stuck trying at the point of making a method call.
I can successfully make a method, but at the point where I am trying to call it, the program breaks.
Test code
The code that I am using to test is
testMethod();
method testMethod () {
print("Test");
}
This generates the following code
Decompiled class
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// AS YOU CAN SEE IT CAN NOT DECOMPILE MAIN METHOD
//
public class test {
public static void main(String[] param0) {
// $FF: Couldn't be decompiled
}
public void testMethod() {
System.out.println("Test");
}
}
Java byte code
.class public test
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 99
.limit locals 99
invokevirtual void/testMethod()V
return
.end method
.method public testMethod()V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Test"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
.limit stack 10
.limit locals 10
return
.end method
What have I tried
I have tried to call the method with the following Java byte code:
(test is the name of the class where I am testing with)
invokevirtual void/testMethod()V
invokevirtual testMethod()V
invokevirtual test/testMethod()V
invokevirtual test/void/testMethod()V
I appreciate any help
As explained by #apangin in the comments, you are trying to call an instance method, so you need an object to call it on, but you did not supply one. You need to create a test instance and push it to the stack prior to calling testMethod, or alternatively mark testMethod as static and invoke it via invokestatic, which is probably easier in this case.
That being said, I would also recommend using the Krakatau assembler rather than Jasmin. Krakatau uses a slightly modified form of Jasmin's syntax which is simpler and less error prone. In particular, in Krakatau, the class name, method name, and method descriptor are separated by spaces, removing a lot of the confusion you had about where you need to put the slashes when calling a method. Krakatau also has other advantages like full support for the bytecode format including Java 14 features, as well as a round trip disassembler which greatly assists with troubleshooting bytecode related issues.
Related
(Trying to keep this simple.)
I have a (partial) ByteBuddy recipe like this:
builder
.method(someMatcher())
.intercept(MethodDelegation.to(this.interceptor));
I have an "interceptor" class defined like this:
private static final class Interceptor {
private Interceptor() {
super();
}
#RuntimeType
private final Object doSomething(#This final Proxy<?> proxy,
#SuperCall final Callable<?> callable,
#Origin final String methodSignature) throws Exception {
final Object proxiedInstance = proxy.getProxiedInstance();
// TODO: logic
return callable.call(); // for now
}
}
(The interceptor method needs to be non-static for various reasons not important here.)
When I create an instance of this ByteBuddy-defined class and call a simple public void blork() method on it, I get:
Cannot resolve ambiguous delegation of public void com.foo.TestExplorations$Frob.blork() to net.bytebuddy.implementation.bind.MethodDelegationBinder$MethodBinding$Builder$Build#3d101b05 or net.bytebuddy.implementation.bind.MethodDelegationBinder$MethodBinding$Builder$Build#1a9efd25
How can there be ambiguity when there is only one interceptor? What have I done wrong?
Byte Buddy just adds a method call to the instrumented class which needs to be able to see the target class. If it is private, it is ignored and Byte Buddy searches further up the hierarchy where it finally consideres the methods of Object which are all equally unsuited but therefore an ambiguity exception is thrown instead of an exception that no method could be bound.
I'm programming in Visual C++ 2010. I've got a example.h example.cpp and Form1.h.
Basically, I've pasted bits of code. I'm not able to include Form1.h in the example.h file, not sure why. But The main question is how do I call Test (which is in form1.h) from example.cpp? What would be the syntax? Is it possible to do this?
My Form1.h
#include "example.h"
public ref class Form1 : public System::Windows::Forms::Form
{
public: void Test(void)
{
// Does something
}
}
My example.cpp
#include "example.h"
#include "Form1.h"
Test(); // would like to call Test from here.
You have two problems here:
You must call functions from inside of another function. The code you currently have in your example.cpp file is invalid, because you are trying to call the Test() function at global scope.
Make it look like this instead:
int main()
{
Test();
return 0;
}
This also solves the problem that you don't have a main function, which is the entry point to any C++ application.
More generally, I would strongly recommend using one of the project templates that comes with Visual Studio to get started (rather than copying and pasting random bits of code, like you said). That ensures that you have all of the things you need to get started, like an entry point. Once you have a solid foundation, you can start building up from there.
You might also find it useful to obtain either a book on C++/CLI or an online tutorial (such as this one: Hello C++/CLI, Part 1 and Hello C++/CLI, Part 2).
Your Test function is a member function of the Form1 class, which means that you need an object of that class in order to call it. Thus, the code should actually look like this:
int main()
{
Form1^ frm = gcnew Form1();
frm.Test();
return 0;
}
Alternatively, you could work around this by making the Test() function a static function. This would allow you to call it without having an instance of the class:
public ref class Form1 : public System::Windows::Forms::Form
{
public: static void Test(void)
{
// Does something
}
}
// ...
int main()
{
Form1::Test();
return 0;
}
However, beware that this means you cannot access any other members of the Form1 class inside of the Test() function (because there is no this pointer).
This should all be explained in whatever book/tutorial you decide to use to learn C++/CLI—search for a chapter about "Classes" or "Object-Oriented Design".
So, I have two classes...Very basic in structure. I try to import one into the other, and declare a new object of that class type...however, it seems to read the class name as the name of a variable?!
The header class provided below will not read the "ApplicationManager" class properly.
Code:
####ifndef _GAME_H_
####define _GAME_H_
####include "application.h"
####include "applicationmanager.h"
class Game : public Application
{
public:
Game();
~Game();
void LoadContent() override;
void UnloadContent() override;
void Draw() override;
private:
//int ApplicationManager; //WHY DOES THIS COMPILE??!
ApplicationManager management; //This DOES NOT WORK?
};
####endif
Here is the header for the "ApplicationManager" class.
Code:
####ifndef _APPMANAGER_H_
####define _APPMANAGER_H_
####include "game.h"
####include "application.h"
class ApplicationManager
{
public:
ApplicationManager(void);
~ApplicationManager(void);
private:
};
####endif
The error that occurs, tells me that I need a ";" before "management", and that "ApplicationManager" is missing a type specifier, so it is assumed to be default-type int.
...any ideas why it won't compile properly? Can someone else try this and report the results? I copied the code, and pasted it in a different solution, to see if something became corrupted....it still didn't work.
You have a cyclic reference. When game.h is included from applicationmanager.h, the ApplicationManager class has not yet been read by the compiler.
To fix, remove the line
#include "game.h"
from applicationmanager.h.
Why do you have circular dependency between Game.h and AppicationManager.h?
Aside from that, I'd say check your header guard (#ifdef _*_H) in Application.h. A fairly often occurence in C++, when copy/pasting code or copying files, is to forget to change the header guard define name for a new class, so you end up with two different headers guarded by the same define. In which case, if both are included into some other file, only the first will actually be expanded into anything useful.
THe error message is some what misleading. It basically says "For some reason (probably an error in the referenced type) I cannot recognize the type you're using (in you case ApplicationManager)".
If you need ApplicationManager to know about Game make a pure virtual base class (interface in other terms) and have Game inherit from that (with out extending the interface) and have ApplicationManager include the base class header file
I am writing a number of small, simple applications which share a common structure and need to do some of the same things in the same ways (e.g. logging, database connection setup, environment setup) and I'm looking for some advice in structuring the reusable components. The code is written in a strongly and statically typed language (e.g. Java or C#, I've had to solve this problem in both). At the moment I've got this:
abstract class EmptyApp //this is the reusable bit
{
//various useful fields: loggers, db connections
abstract function body()
function run()
{
//do setup
this.body()
//do cleanup
}
}
class theApp extends EmptyApp //this is a given app
{
function body()
{
//do stuff using some fields from EmptyApp
}
function main()
{
theApp app = new theApp()
app.run()
}
}
Is there a better way? Perhaps as follows? I'm having trouble weighing the trade-offs...
abstract class EmptyApp
{
//various fields
}
class ReusableBits
{
static function doSetup(EmptyApp theApp)
static function doCleanup(EmptyApp theApp)
}
class theApp extends EmptyApp
{
function main()
{
ReusableBits.doSetup(this);
//do stuff using some fields from EmptyApp
ReusableBits.doCleanup(this);
}
}
One obvious tradeoff is that with option 2, the 'framework' can't wrap the app in a try-catch block...
I've always favored re-use through composition (your second option) rather than inheritance (your first option).
Inheritance should only be used when there is a relationship between the classes rather than for code reuse.
So for your example I would have multiple ReusableBits classes each doing 1 thing that each application a make use of as/when required.
This allows each application to re-use the parts of your framework that are relevant for that specific application without being forced to take everything, Allowing the individual applications more freedom. Re-use through inheritance can sometimes become very restrictive if you have some applications in the future that don't exactly fit into the structure you have in mind today.
You will also find unit testing and test driven development much easier if you break your framework up into separate utilities.
Why not make the framework call onto your customisable code ? So your client creates some object, and injects it into the framework. The framework initialises, calls setup() etc., and then calls your client's code. Upon completion (or even after a thrown exception), the framework then calls cleanup() and exits.
So your client would simply implement an interface such as (in Java)
public interface ClientCode {
void runClientStuff(); // for the sake of argument
}
and the framework code is configured with an implementation of this, and calls runClientStuff() whenever required.
So you don't derive from the application framework, but simply provide a class conforming to a particular contract. You can configure the application setup at runtime (e.g. what class the client will provide to the app) since you're not deriving from the app and so your dependency isn't static.
The above interface can be extended to have multiple methods, and the application can call the required methods at different stages in the lifecycle (e.g. to provide client-specific setup/cleanup) but that's an example of feature creep :-)
Remember, inheritance is only a good choice if all the object that are inheriting reuse the code duo to their similarities. or if you want callers to be able to interact with them in the same fission.
if what i just mentioned applies to you then based on my experience its always better to have the common logic in your base/abstract class.
this is how i would re-write your sample app in C#.
abstract class BaseClass
{
string field1 = "Hello World";
string field2 = "Goodbye World";
public void Start()
{
Console.WriteLine("Starting.");
Setup();
CustomWork();
Cleanup();
}
public virtual void Setup()
{Console.WriteLine("Doing Base Setup.");}
public virtual void Cleanup()
{Console.WriteLine("Doing Base Cleanup.");}
public abstract void CustomWork();
}
class MyClass : BaseClass
{
public override void CustomWork()
{Console.WriteLine("Doing Custome work.");}
public override void Cleanup()
{
Console.WriteLine("Doing Custom Cleanup");
//You can skip the next line if you want to replace the
//cleanup code rather than extending it
base.Cleanup();
}
}
void Main()
{
MyClass worker = new MyClass();
worker.Start();
}
Using ildasm and a C# program e.g.
static void Main(string[] args)
{
}
gives:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::Main
What does the hidebysig construct do?
From ECMA 335, section 8.10.4 of partition 1:
The CTS provides independent control
over both the names that are visible
from a base type (hiding) and the
sharing of layout slots in the derived
class (overriding). Hiding is
controlled by marking a member in the
derived class as either hide by name
or hide by name-and-signature. Hiding
is always performed based on the kind
of member, that is, derived field
names can hide base field names, but
not method names, property names, or
event names. If a derived member is
marked hide by name, then members of
the same kind in the base class with
the same name are not visible in the
derived class; if the member is marked
hide by name-and-signature then only a
member of the same kind with exactly
the same name and type (for fields) or
method signature (for methods) is
hidden from the derived class.
Implementation of the distinction
between these two forms of hiding is
provided entirely by source language
compilers and the reflection library;
it has no direct impact on the VES
itself.
(It's not immediately clear from that, but hidebysig means "hide by name-and-signature".)
Also in section 15.4.2.2 of partition 2:
hidebysig is supplied for the use of
tools and is ignored by the VES. It
specifies that the declared method
hides all methods of the base class
types that have a matching method
signature; when omitted, the method
should hide all methods of the same
name, regardless of the signature.
As an example, suppose you have:
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
That's valid, because Bar(string) doesn't hide Bar(), because the C# compiler uses hidebysig. If it used "hide by name" semantics, you wouldn't be able to call Bar() at all on a reference of type Derived, although you could still cast it to Base and call it that way.
EDIT: I've just tried this by compiling the above code to a DLL, ildasming it, removing hidebysig for Bar() and Bar(string), ilasming it again, then trying to call Bar() from other code:
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments
However:
Base d = new Derived();
d.Bar();
(No compilation problems.)
As per THE SKEET's answer, in addition the reason for this is that Java and C# allow the client of a class to call any methods with the same name, including those from base classes. Whereas C++ does not: if the derived class defines even a single method with the same name as a method in the base class, then the client cannot directly call the base class method, even if it doesn't take the same arguments. So the feature was included in CIL to support both approaches to overloading.
In C++ you can effectively import one named set of overloads from the base class with a using directive, so that they become part of the "overload set" for that method name.
According to Microsoft Docs
When a member in a derived class is declared with the C# new modifier
or the Visual Basic Shadows modifier, it can hide a member of the same
name in the base class. C# hides base class members by signature. That
is, if the base class member has multiple overloads, the only one that
is hidden is the one that has the identical signature. By contrast,
Visual Basic hides all the base class overloads. Thus, IsHideBySig
returns false on a member declared with the Visual Basic Shadows
modifier, and true on a member declared with the C# new modifier.