C# integration in Clarion with OLE and COM dll - clarion

I've written a small test COM dll in c# and registered it. I would like to call this from Clarion.
So far in clarion I have the following code
?OLE{PROP:Create} = 'test.test_COM'
oc:MicData = ?OLE{ 'SayHello("myname")' }
The problem I'm having is there is a class testClass_COM and the function SayHello actually lies in the class. How can I access the function or create an object in clarion with the class testClass_COM and access the function that way.
Thanks in advance for any help

The code you show says that the class is called test_COM but then you say the class is called testClass_COM:
?OLE{PROP:Create} = 'test.testClass_COM'
oc:MicData = ?OLE{ 'SayHello("myname")' }
anyway I will enable errors like this to get more details on what is going on:
?OLE{PROP:Create} = 'test.testClass_COM'
?Ole{PROP:ReportException} = true
oc:MicData = ?OLE{ 'SayHello("myname")' }

Related

Unreal engine UPROPERTY TsubclassOf not recognized

When I've created an ActorComponent c++ subclass with TSubclassOf UPROPERTY and set this class in blueprint I can't read read this property in c++ constructor.
In .h file I've got this:
protected:
UPROPERTY(EditAnywhere, Category = "Setup")
TSubclassOf<UBaseSkill> PrimarySkillClass;
And this in .cpp:
USkillSet::USkillSet()
{
if(PrimarySkillClass.Get())
{
UE_LOG(LogTemp, Warning, TEXT("Creating skill"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("No skill class"));
}
}
In BP I'm setting a class:
BP screenshot
so PrimarySkillClass.Get() should return true, but I'm getting "No skill class" in log. Why and how could I fix this?
The constructor is the first method ever called on an object, it's to early on the life of the UObject. Properties, values from Blueprints and components are initialized afterwards.
So you have to access them later, either on UObject::PostInitProperties() or on BeginPlay() if it's not too late for your purpose.
Edit: interesting reading on UObject Constructor, PostInitProperties and PostLoad

Excel-Dna get globals properties

I am using excel-dna as base function, then I call a "vsto" function from an addin to trigger a web service request on the selected function. My issue is that I d like to use the DNA function to parse the ranges to be send to the service. It return a string currently ("waiting for service call..."), and if the VSTO methods call the function it passed another variable to return something else.
I cannot extract other thing than string, object comes back empty when I use "evaluate" in vsto.
I think the best way would be to reach a global cache variable stored in the vsto addin from the excel-dna function. I could not manage to to this.
Addins button push => addins evaluate Excel DNA => DNA store data in VSTO Addin variable => VSTO call the service and paste the returning data.
Thank you,
Ok I found out on:
MSN Blog
namespace AddIn{
[ComVisible(true)]
[Guid("****************************")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddinUtilities
{ void youraddinfunction();
}
[ClassInterface(ClassInterfaceType.None)]
public partial class ThisAddIn : IAddinUtilities
{
protected override object RequestComAddInAutomationService()
{ return this; }
public void yourfunction (){ DoSomething }
}
In the excel Dna function :
var application = (Application)XL.ExcelDnaUtil.Application;
var addin = application.COMAddIns.Item(AddinName);
var what = addin.Object;
what.youraddinfunction;
Yoyo's approach is strictly speaking correct, but for an approach that is more portable, I suggest combining ExcelDNA with NetOffice. Here is a snippet to get you started. Note that you will need to cleanup your Application references to COM proxy objects in the OnDisconnection method. For more details, check out Excel Addin Portability Tutorial
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ProgId("Sample.MyAddIn")]
public class MyRibbon : ExcelRibbon
{
public override void OnConnection(object comApp, ext_ConnectMode ConnectMode, object objAddin, ref Array custom)
{
// glue NetOffice + Excel DNA
m_ExcelApplication = new Application(null, m_ComApplication);
// other initialization...
}
}

Lambda expressions (C++0x) not working in C++/CLI? [duplicate]

One of the cool new C++ features in Visual Studio 2010 are lambda expressions. However, I can't get them to work within a managed class.
class UnmanagedClass {
void Foo() {
// Creating empty lambda within unmanaged class.
// This compiles fine.
auto lambda = [](){ ; };
}
};
ref class ManagedClass {
void Foo() {
// Creating empty lambda within managed class.
// This creates error C3809:
// A managed type cannot have any friend functions/classes/interfaces.
auto lambda = [](){ ; };
}
};
My best guess is that the compiler creates the anonymous function class as a friend class, even though I never use class members. This seems to mean that lambdas cannot be used at all within ref classes.
I was so happy when I read that VS2010 adds lambda expressions to C++. Does anybody know how to get them to work within ref classes?
Looks like it is being considered for future versions. Otherwise known as: "We'll get to it."

ATL/COM : In IDL file can we create a class which can be used as return type

I was working on COM/ATL. I need to use a class object as return value so that it can be used in managed code. I am able to define structure in idl file and also able to use it as return parameter when creating methods.
Below is the partial idl file implementation:
import "oaidl.idl";
import "ocidl.idl";
//Structure for message mapping of activation and deactivation
//Structures are working properly
[uuid(E2240D8B-EB97-4ACD-AC96-21F2EAFFE100)]
struct tagActivationManaged
{
WORD wMsgId;
WORD wStatus;
WORD wClient;
WORD wClientId;
};
//same manner if creating class it throws error.
[uuid(2ED2E59C-9362-46b2-80D8-471AD69BA5D5)]
class AuthenticationMessage
{
public:
Word message;
}
do I need to change any settings in MIDL.
NB: I am new to COM programming.
You just can't do that - there're no C++ flavor classes in IDL. If you want to return an object of some class from a function you have to declare an interface and possibly a coclass (the latter may not be required depending on your sitiation) and make the function return that interface.

C#<-->JScript: invisible array?

I have a bit of a complex program which is giving me this apparently phantom error...
I'll start explaining with the help of this little example program I rigged that can throw my beautiful exception for anyone who runs it.
<!-- language: c# -->
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace so_redux {
static class Program {
[STAThread]
static void Main(){
CS2JS _class=new CS2JS();
}
}//class Program
class CS2JS{
public CS2JS(){
Func<String,Object> js_eval=initJS();
Object cs_ic=initCS();
string xc;
object res;
cs_ic.GetType().GetMethod("init").Invoke(cs_ic,null);
AppDomain.CurrentDomain.SetData("trespasser",cs_ic);
xc=#"function edata(fieldname:String,ival:String):Object{
var sob=System.AppDomain.CurrentDomain.GetData('trespasser');
var v1=sob.GetType().GetField(fieldname).GetValue(sob);
function HASH(s1:String,s2:String):Object{
var q1=sob.GetType().GetField(s1).GetValue(sob);
return q1.ITEM(s2);
}
var v2=v1.ITEM(ival);
return eval(v2);
}
edata('HT','foo');";
res=js_eval(xc);
// var xx;xx=new Hashtable();xx['sda']='1';eval(xx['sda']); OK
}
Func<String,Object> initJS(){
System.CodeDom.Compiler.CodeDomProvider jcc;
System.CodeDom.Compiler.CompilerParameters jcp;
System.CodeDom.Compiler.CompilerResults jcr;
System.Reflection.Assembly jas;
object jis;
string code;
Type t_ii;
code=#"#set #debug(off)
import System;
import System.Collections;
import System.Collections.Generic;
package internal_namespace{class internal_class{
public function internal_method(_code:String):Object{
return eval(_code);
}
}
}";
jcc=Microsoft.JScript.JScriptCodeProvider.CreateProvider("JScript");
jcp=new System.CodeDom.Compiler.CompilerParameters();
jcp.CompilerOptions="/fast-";
jcp.GenerateExecutable=false;
jcp.GenerateInMemory=true;
jcp.IncludeDebugInformation=false;
jcp.ReferencedAssemblies.Add("System.dll");
jcp.ReferencedAssemblies.Add("System.Core.dll");
jcp.WarningLevel=4;
jcr=jcc.CompileAssemblyFromSource(jcp,code);
jas=jcr.CompiledAssembly;
jis=jas.CreateInstance("internal_namespace.internal_class");
t_ii=jas.GetType("internal_namespace.internal_class");
return (s1)=>t_ii.InvokeMember("internal_method",System.Reflection.BindingFlags.InvokeMethod,null,jis,new object[]{s1});
}//initJS
Object initCS(){
var v1= Microsoft.CSharp.CSharpCodeProvider.CreateProvider("CSharp");
System.CodeDom.Compiler.CompilerParameters v2=new System.CodeDom.Compiler.CompilerParameters();
v2.GenerateExecutable=false;
v2.GenerateInMemory=true;
v2.IncludeDebugInformation=false;
v2.WarningLevel=4;
v2.ReferencedAssemblies.Add("System.dll");
v2.ReferencedAssemblies.Add("System.Core.dll");
string _code="public Hashtable2 HT;"+
"public void init(){"+
"HT=new Hashtable2();"+
"HT[\"foo\"]=\"1\";"+
"HT[\"bar\"]=\"HASH('HT','foo')\";"+
"}";
var v3="using System;using System.Collections;using System.Collections.Generic;"+
"namespace internal_namespace{public class Hashtable2:Hashtable{"+
"public Hashtable2():base(){} public Hashtable2(int N):base(N){}"+
"public Object ITEM(Object K){return this[K];} }"+
"[Serializable]public class internal_class{"+
"public internal_class(){}"+
_code+
"\n}}";
var v4=v1.CompileAssemblyFromSource(v2,v3);
var v5=v4.CompiledAssembly;
var v6=v5.GetType("internal_namespace.internal_class");
var v7=v5.CreateInstance("internal_namespace.internal_class");
return v7;
}//initCS
}//class CS2JS
}//namespace so_redux
The exception that is thrown is "index out of bounds", and it's thrown from JScript. The problem? It's that there is no array!
What this code is doing: first a JScript interpreter is initialized by compiling at runtime a class that "exports" an eval (one could do a dll, but in this case I didn't).
Then a C# assembly is compiled, an assembly that "exports" some user code (the variable _code in initCS is originally loaded by reading a text file).
After the initialization of the newly compiled class (the invoking of init()), I need the two assemblies (JScript and C#) to interact, so I need to pass data between them, and I thought of using AppDomain.
Note: in the C# assembly an Hashtable2 is defined because I put in there an ITEM method that one can use in alternative to the common property this[]: in this way debugging is easier (for examply by showing a holy MessageBox when accessing the values).
So, I pass the class instantiated in initCS to JScript, and JScript reads the internal Hashtable (HT). What I need to do is evaluate the data in the Hashtable, because it is supposed to be able to alter itself dynamically.
Everything works fine if I eval a string not taken from the Hashtable -- in the moment I take whatever is in the Hashtable and pass it to eval, then exceptions happen. Attention: the strings are absolutely the same (even comparing them with Equals) and they work, the difference is only from where they come from.
When the JScript function edata evals a string taken from the Hashtable, JScript says "index out of bounds", but as I was saying: I don't see any array there... (and maybe the problem is exactly that, dunno).
I admit I have my limitations in JScript, so if anybody could lend a hand to help understand WTF is going on, I would be really happy.
Temporary solution/workaround splitting the JScript function:
xc=#"function odata(fieldname:String,ival:String):Object{
var sob=System.AppDomain.CurrentDomain.GetData('trespasser');
var v1=sob.GetType().GetField(fieldname).GetValue(sob);
return v1.ITEM(ival);
}
odata('HT','bar');";
res=js_eval(xc);
xc=#"function HASH(s1:String,s2:String):Object{
var sob=System.AppDomain.CurrentDomain.GetData('trespasser');
var q1=sob.GetType().GetField(s1).GetValue(sob);
return q1.ITEM(s2);
}
eval("+res.ToString()+");";
res=js_eval(xc);
but if anybody really got any idea of why is wrong in the first example, please explain me!

Resources