Ironpython - Issues attaching to an instance of an already running program - com

Ok folks this is a long one, so please bear with me. I'll preface this by stating that I am -for all intents and purposes- a noob.
I'm trying to link to a running instance of a program (ETABS) using IronPython. The program has an API and decent documentation on how one can go about hooking into the running instance (EXAMPLE). However, their examples are for Python, C#, VB.net but not IronPython.
No biggie I thought, the Marshal module can be used to hook into it. So I tried this:
from System.Runtime.InteropServices import Marshal
csiApp = Marshal.GetActiveObject("CSI.ETABS.API.ETABSObject")
SapModel=csiApp.SapModel
Unfortunately I get errors on that last line - "ETABSObject has no attribute SapModel".
And yes, I've tried running it with csiApp.SapModel() as well with the same results.
So I delved deeper into it and apparently the object needs to be cast into another type - at least that's the way its been done for the C# example (LINK). Since - to my knowledge - we can't really cast objects around in Python (and yes, I've already tried clr.Convert) I came to the conclusion that the object being returned to Ironpython is a few abstractions removed from the object that I really need. Apparently comtypes can handle this automatically in the background (seeing as the python example works flawlessly). The code block below shows the object types returned to Ironpython and to pure python respectively:
Ipy : <System.MarshalByRefObject object at 0x000000000000002B [CSI.ETABS.API.ETABSObject]>
Python with comtypes : <POINTER(cOAPI) ptr=0x2e68d17f7c8 at 2e690b36a48>
I'm working on Ironpython 2.7.3 and can't really update it (for several reasons not relevant to this post). Would love to have advice on how to fix this or on how to install comtypes on Ipy.

So I think I've found the reason why this is happening - Ironpython cannot directly use MarshalByRefObjects (source) since Reflection doesn't work on these. It seems I'll need to create a C# class which can cast this object into the one I want, compile it into a dll and load that into my Ipy code.
I'll leave this here in case someone with more knowledge has a better answer.

Related

How to list the exposed members of a package/dir-like method in Elm?

I have been searching the official docs and existing questions and could not find any information on this - in Elm, how it would be possible to see the members/methods/variables that belong to or are exposed by a package in Elm, (such as the dir method in python), without having to dive into the source code each time?
What I want to do is get a simple list of what methods are exposed by an imported package. (So for a package like List, it should output reverse , all, any, map, etc.) I have attempted tab completion in elm repl and the elm extension available in VS code editor, and elm repl does not offer any methods such as help, doc, ?, dir, man, etc., so I have no idea where to even start. I'm wondering how everyone else does this other than pulling up the source code for each and every package they use.
I apologize for the newbie question and if I misread or have been missing anything, but I couldn't even find anything in the https://elmprogramming.com tutorial. Thanks in advance.
Nothing like this exists in Elm to do reflection over modules, unfortunately (as of 0.19.1, at least).
However, if you aren't looking to actually do this kind of thing at runtime, but rather as a convenient way of finding out for development, the elm packaging system enforces the requirement that all public functions are documented, so if you visit the package page, every public function and type will be documented there (obviously it can't enforce the content of the documentation, but at the very least it will be listed).

Can FsXaml be used in an F# interpreted script?

I just converted one of the FsXaml demo programs to an interpreted F# script so I could experiment with it and learn. It wouldn't run, and the interpreter gave me the following error message:
System.NotSupportedException: The invoked member is not supported in a
dynamic assembly.
at System.Reflection.Emit.InternalAssemblyBuilder.GetManifestResourceStream(String
name)
at FsXaml.InjectXaml.from(String file, Object root)
at
FsXaml.App.InitializeComponent() at FsXaml.App..ctor()
at
FSI_0002.main[a](a argv)
in C:\Users\bobmc\OneDrive\FSharp\Learning\WPFExamples\FsXaml\demos\WpfSimpleMvvmApplication\WPFApp.fsx:line 104
at .$FSI_0002.main#() in
C:\Users\bobmc\OneDrive\FSharp\Learning\WPFExamples\FsXaml\demos\WpfSimpleMvvmApplication\WPFApp.fsx:line
109
Can I use the F# interpreter with FsXaml? Thanks to all for your help.
Unfortunately, WPF and scripts don't play well together.
The exception occurs within the WPF runtime itself - FsXaml.InjectXaml is using a XamlObjectWriter to populate the type with the contents from the XAML file. This type doesn't work if you're using a dynamic assembly (like FSI), which unfortunately means that FsXaml will likely never be able to work from FSI.
That being said, even if there was a way around this, it'd be of very limited use. WPF also has restrictions that make it not play well with a scripting scenario, such as the "only one application can ever be created within a given AppDomain" restriction. That one makes it so closing the "main" (first) window makes it so you can never open another one. As such, I haven't prioritized trying to make this work in FSI.
I'd be happy to accept contributions if somebody has an idea of how to make FsXaml play more nicely within the context of FSI, but at this point, I don't see a good solution for that usage scenario.
Edit: FsXaml 3.1.6 now includes functionality to make this a lot easier. It works well, provided you don't close the main window, or you use dialogs. There is a demo application/script illustrating this.

Using StatePrinter from VB rather than C# to implement ToString

I'm trying to follow the promising suggestion posted here to try StatePrinter as a shortcut to rolling my own ToString methods. I agree with the OP that it is a shame that VS still can't generate this method for me.
I've got a fairly large project, in VS2015 (Community Edition), with both VB and C# code. I added the current stable version of StatePrinter using NuGet.
I can make the example code from the SO answer work fine in my C# code but when I do what I think is the equivalent in my VB code:
Private Shared sp As StatePrinter.Stateprinter = New StatePrinter.Stateprinter
Public Overrides Function ToString() As String
Return sp.PrintObject(Me)
End Function
I just get the compiler error
'Stateprinter' is ambiguous in the namespace 'StatePrinter'
There IS another constructor, StatePrinter (note difference in capitalization only) which is deprecated and, in any case, generates the same error message.
I'm led to the unfortunate conclusions that
VB in VS2015 is acting as if it is case insensitive. Can that be true?
No one else is using StatePrinter from VB.
Can anyone provide any suggestions on how to use StatePrinter from VB? I'm willing to believe I'm making some rather brain-dead mistake in converting the C# example to VB.
It is near impossible to use this directly in VB and get around the ambiguous name issue. You could write a class library wrapper in C# that doesn't expose this mismatch (that is, it has an internal StatePrinter object and exposes constructors that are PascalCased the same.
Another option would be to use reflection in the VB project to get around the case insensitivity.
You could also create a GitHub issue. Or, be a contributor to the project and create a suggested fix for it. :)
As soon as I got done writing #1 in the question above, I was able to figure out how to search for the answer to that bit.
Yes, VB is case insensitive, at least, as far as it needs to be in this case:
See the rather nice writeup here:
https://stackoverflow.com/a/2301980/165164
So, we're left with the rather plaintive: is no one else using StatePrinter from VB?

Debugging interpreter in VM when changing vm primitives

Context
As a university project we want to change the the pharo vm to use an object-table and see what happens.
We use a pharo-vm clone from github and VMMaker. Building the VM works fine.
To get started we added a primitive that returns an incremented Integer:
InterpreterPrimitives>>primitiveIntegerIncrement
"increments an integer"
self pushInteger: self popInteger + 1 .
and modified StackInterpreter class>>initializePrimitiveTable accordingly
MaxPrimitiveIndex := 576.
"... and so on ..."
(575 primitiveFail)
(576 primitiveIntegerIncrement))
And it works.
Problem
When we make changes to the VM we want to test-run already in the SmalltalkImage so we do not need to compile and see it did not work.
Something like:
StackInterpreter test: '1 inc'
And then I can debug if the primitive is wrong or an error occurs. Of course there needs to be done much more but how can I achieve this?
What we tried
category VMMaker-InterpreterSimulation class StackInterpreterSimulator. Trying the code in the comments
DoIt
^ (StackInterpreterSimulator new openOn: Smalltalk imageName) test
errors:
displayForm := 'Display has not yet been installed' asDisplayText form.
the ByteString does not understand asDisplayText
(CogVMSimulator new openOn: Smalltalk imageName) test
(InterpreterSimulator new openOn: Smalltalk imageName) test
error:
PrimitiveFailed: primitive #basicNew: in Array class failed
I also found this screen cast but it only debugs the VM from outside using gbd: http://vimeo.com/22485382#
Our project is hosted here: http://smalltalkhub.com/#!/~kirstin/PharoObjectTable
Current Status
We started implementing an object table. The lookup of attributes can go throught the object table. Full object table support and no usage of direct pointes is very tricky since pointers are expected everywhere. So we use pointers into the object table to identify when a lookup should go through the OT. We also found all object creation primitives and add new objects to the table.
How long is your project and how many people are you ? To me what you try to do is quite some work. Do you have good knowledge about low level behavior ?
To answer your question, the main problem here is that the cog simulator is not maintained in the pharo vm fork. This is because no one in the pharo crew use the simulator. We only use external debugging from gdb. In fact the pharo folks work mostly on VM plugins, the core of the VM is mainly maintained and developed by Eliot Miranda which works on Squeak. Therefore we report to him when there's a bug in the VM core.
For your project you would have to split it in at least 2 steps:
step 1: make the object table work with the stack VM
step 2: make the JIT work with your object table
Note that for step 2 I would recommend not to change the way an object access its header, therefore having a VW-like object table where you have the fixed size header on the one in the the object table, and the fields of the objects (and maybe header extensions) in the heap.
So use the StackVMSimulator and build the StackVM first. When everything will work (including context), you can think about hacking the JIT. Recently Guillermo Polito ported the Stack VM to the build process (see PharoSVMBuilder instead of PharoVMBuilder), a guy reported problems with this builder but you could hack it a bit to make it work.
Now to make the simulator work on Pharo 2.0 (which is the Pharo version of the generator image you have), you have to open the monticello browser and merge from Eliot's branch the Cog package (repo MCHttpRepository location: 'http: //source. squeak. org/VMMaker'), but not the latest Cog, the one at around the same date as the current VMMaker package of pharo-vm because the latest Cog and VMMaker of Eliot's branch are not stable.
The alternative being to start from Eliot's build image and merge things from the pharo branch. Here are infos about how to build the squeak development image (http://www.mirandabanda.org/cogblog/build-image/).
Then Eliot gave me this script once:
| cos |
cos := CogVMSimulator newWithOptions: #(Cogit SistaStackToRegisterMappingCogit).
cos desiredNumStackPages: 8.
cos openOn: 'my/favourite.image'.
cos openAsMorph; toggleTranscript; halt; run
You don't need the SistaStackToRegisterMappingCogit option. I guess some similar script with the StackVMSimulator should work.
Lastly there are some documentation about the simulator but it is only for the CogSimulator (these documentations expects you already knows how the StackSimulator works, and just give you hints about how to use it with the JIT):
http://www.mirandabanda.org/cogblog/2008/12/12/simulate-out-of-the-bochs/
and in one of the video named "Cog VM (part x)", x being from 1 to 6, Eliot shows how he uses the simulator to disassemble x86, print the stack and inspect the heap.
Another tip, ask your questions on the pharo mailing list (pharo users or pharo dev), because here no one may notice your question (fortunately someone pointed me out your question this time).
And tell on the pharo mailing list if you managed to run the simulator in Pharo 2.0, some people (as me) are very interested in it. I was planning to do it at some point.
Good luck ! Nice project anyway.
The last time I tried to use the simulator is roughly a year ago, and I did not make it work.
However, there are a few patches, which I assume never got integrated that might be of help:
https://code.google.com/p/cog/issues/detail?id=106
https://code.google.com/p/cog/issues/detail?id=107
https://code.google.com/p/cog/issues/detail?id=108
Issue 107 includes a patch for your asDisplayText issue.

Is there a way to mix MonoTouch and Objective-C?

I'd like to know if there is a way to mix C# and Obj-C code in one project. Specifically, I'd like to use Cocos2D for my UI in Obj-C and call some MonoTouch C#-Library that does some computations and get some values back. Is there a way to do this? Or maybe the other way around, i. e. building in MonoTouch and calling Cocos2D-functions?
Thanks.
The setup that you describe is possible, but the pipeline is not as smooth as it is when you do your entire project in MonoTouch. This is in fact how we bootstrapped MonoTouch: we took an existing Objective-C sample and we then replaced the bits one by one with managed code.
We dropped those samples as they bitrot.
But you can still get this done, use the mtouch's --xcode command line option to generate a sample program for you, and then copy the bits that you want from the generated template.m into your main.m. Customize the components that you want, and just start the XCode project from there.
During your development cycle, you will continue to use mtouch --xcode
Re: unknown (google):
We actually did this as described.
See this page for a quick start, but the last code segment on that page is wrong, because it's omitting the "--xcode"-parameter.
http://monotouch.net/Documentation/XCode
What you have to do to embed your Mono-EXE/DLL into an Objective-C program is to compile your source with SharpDevelop, then run mtouch with these parameters:
/Developer/MonoTouch/usr/bin/mtouch --linksdkonly --xcode=output_dir MyMonoAssembly.exe
This only works with the full version of MonoTouch. The trial does not allow to use the "--xcode"-argument . The "--linksdkonly"-argument is needed if you want mtouch to keep unreferenced classes in the compiled output, otherwise it strips unused code.
Then mtouch compiles your assembly into native ARM-code (file extension .s) and also generates a XCode template which loads the Mono-Runtime and your code inside the XCode/ObjC-program. You can now use this template right away and include your Obj-C-code or extract the runtime loading code from the "main.m"-file and insert it into your existing XCode-project. If you use an existing project you also have to copy all .exe/.dll/.s files from the xcode-output-dir that mtouch made.
Now you have your Mono-Runtime and assembly loaded in an XCode-project. To communicate with your assembly, you have to use the Mono-Embedding-API (not part of MonoTouch, but Mono). These are C-style API calls. For a good introduction see this page.
Also the Mono-Embedding-API documentation might be helpful.
What you have to do now in your Obj-C-code is to make Embedding-API calls. These steps might involve: Get the application domain, get the assembly, get the image of the assembly, locate the class you want to use, instantiate an object from that class, find methods in class, call methods on object, encapsulate method arguments in C-arrays and pass them to the method-call, get and extract method return values.
There are examples for this on the embedding-api-doc-page above.
You just have to be careful with memory consumption of your library, as the mono runtime takes some memory as well.
So this is the way from Obj-C to C#. If you want to make calls from C#/Mono into your Obj-C-program, you have to use the MonoTouch-bindings, which are described here.
You could also use pure C-method calls from the embedding/P/Invoke-API.
Hope this gets you started.
Over the weekend it emerged that someone has been porting Cocos2D to .NET, so you could also do the whole work on .NET:
http://github.com/city41/CocosNet
Cocos2D started as a Python project, that later got ported to Objective-C, and now there is an active effort to bring it to C#. It is not finished, but the author is accepting patches and might be a better way forward.
Calling Objective-C from MonoTouch definitely looks possible. See the Objective-C selector examples
What library are you calling? Perhaps there's an Objective-C equivalent.