C# calls the function of Cpython - c#

This is the code I copy, and I want to learn to use Python.Runtime, but when it runs, it throws an exception.
"DLL" python2.7m "cannot be loaded: no specified module can be found. (the exception comes from HRESULT:0X8007007E). "
As a problem with a rookie. Thank you.
using Python.Runtime;
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
using (Py.GIL())
{
dynamic np = Py.Import("numpy");
dynamic sin = np.sin;
Console.WriteLine(np.cos(np.pi * 2));
Console.WriteLine(sin(5));
double c = np.cos(5) + sin(5);
Console.WriteLine(c);
Console.ReadKey();
}
}
}
}

Related

when i use C# dll from C++ for using Selenium, there is exception handling problem [duplicate]

This question already has an answer here:
Use selenium with C
(1 answer)
Closed 2 years ago.
It works well on the c# code. However, an exception handling error occurs if i execute at c++ with c# dll.
First, I'll show you my code.
C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace ManagedLibrary1
{
public interface LoginClass
{
void LogIn(string id, string pw, int t, int num);
void LogOut();
}
public class Class1 : LoginClass
{
IWebDriver driver = new ChromeDriver();
IWebElement a;
Boolean b;
public void LogIn(string id, string pw, int t, int num)
{
if (num == 0)
{
driver.Navigate().GoToUrl("this is url address");
}
else
{
driver.Url = "this is url address2";
}
Thread.Sleep(50);
if (t == 0)
{
a = driver.FindElement(By.XPath("this is Xpath"));
b = a.Displayed;
if (b == true)
{
a.Click();
}
}
driver.FindElement(By.XPath("this is xpath2")).SendKeys(id);
Thread.Sleep(50);
driver.FindElement(By.XPath("this is xpath3"]")).SendKeys(pw);
Thread.Sleep(50);
driver.FindElement(By.XPath("this is xpath4")).Click();
Thread.Sleep(5000);
a = driver.FindElement(By.XPath("this is xpath5"));
if (b == true)
{
driver.Url = "this is url address 3";
}
driver.Manage().Window.Maximize();
driver.FindElement(By.ClassName("this is classname")).Click();
}
public void LogOut()
{
a = driver.FindElement(By.XPath("this is xpath6"));
b = a.Displayed;
if (b == true)
{
a.Click();
}
}
}
}
C++ code
#include <windows.h>
#include "tchar.h"
#import "C:\Users\me\Desktop\Project Folder\ClassLibrary4\ClassLibrary4\bin\Debug\ClassLibrary4.tlb" raw_interface_only
using namespace ClassLibrary4;
int main()
{
HRESULT hr = CoInitialize(NULL);
LoginClassPtr pICalc(__uuidof(Class1));
pICalc->LogIn("id","password",1,0);
CoUninitialize();
return 0;
}
when debugging C++ code, error generate here
LoginClassPtr pICalc(__uuidof(Class1));
If the process of receiving the function of dll was wrong, I tried to change the function part of C# into very simple function that calculates the sum of two integers, and it worked well without errors.
Only this one problem has kept me from going forward for two days. I want your help.
I was working on similar issue, my c# dll was signed dll with a strong name. The selenium webdriver nuget package i was using was not having a strong name. Apparently strong named dll cannot load another dll which is not having strong name. I uninstalled selenium webdriver package and installed selenium webdriver.strongname ,this worked for me.

when i create and construct 2 objects of the same type, they copy each other to the last constructed object

im a noob in c#. My problem comes when i want to create 2 objects
two_digt d1,d2;
of course i got to call for two_digt(int n) to create an object. But when i do it for d1 and d2, the last one called overwrites the first. Let me introduce to you my c# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class two_digt {
private static int dgt1, dgt2;
public two_digt(int n) {//constructor
dgt1 = n % 10;
dgt2 = (n % 100)/10;
}
public void print() {//funct to show what they've got
Console.WriteLine("dgt1:"+ dgt1 );
Console.WriteLine("dgt2:"+ dgt2 );
}
}
class Program
{
static void Main(string[] args)
{
two_digt d1 = new two_digt(Convert.ToInt32(Console.ReadLine()));
d1.print();
two_digt d2 = new two_digt(Convert.ToInt32(Console.ReadLine()));
//printing each objects
d2.print();
d1.print();
Console.ReadLine();//just to keep console from closing
}
}
}
Now i will show you the program i/o:
input:
1234
8765
//as you can suggest from my code "two_digt" will took for the
//first 2 digits of both numbers
output:
//d1.print();
dgt1:4
dgt2:3
//d2.print();
dgt1:6
dgt2:5
//d1.print();
dgt1:6
dgt2:5
//What...?
that is actually my issue and i dont understand what .net framework does with data structures, please leave an answer to this ,or, if you can, leave a pro explanation.
The problem is that dgt1, dgt2 are static. Remove the static modifier and you should get separate values.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class two_digt
{
private int dgt1, dgt2;
public two_digt(int n)
{//constructor
dgt1 = n % 10;
dgt2 = (n % 100) / 10;
}
public void print()
{//funct to show what they've got
Console.WriteLine("dgt1:" + dgt1);
Console.WriteLine("dgt2:" + dgt2);
}
}
class Program
{
static void Main(string[] args)
{
two_digt d1 = new two_digt(Convert.ToInt32(Console.ReadLine()));
d1.print();
two_digt d2 = new two_digt(Convert.ToInt32(Console.ReadLine()));
//printing each objects
d2.print();
d1.print();
Console.ReadLine();//just to keep console from closing
}
}
}

Error 1 The name 'WriteAt' does not exist in the current context

I'm trying to write a game in C# that runs on my cmd on Windows and I need to be able to write to any part of the box to do that. I found WriteAt used extensively for this purpose, however it doesn't seem to work in VS 2010. I get the error: "The name WriteAt does not exist in the current context"
I have the default:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
at the top of my code. So why can't I use WriteAt?
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GamePCL
{
class Program
{
static void Main(string[] args)
{
Console.Clear();
for (int x = 0; x < 24; x += 2)
{
WriteAt("█", x, 0);
WriteAt("█", x, 30);
}
}
}
}
When you call a method without an object or type prefix, as in this case WriteAt() (as opposed to for example Console.WriteLine(), which is called on the Console type), the method must exist in the current context, i.e. in the current class.
You copied that code from MSDN without copying the relevant method:
protected static void WriteAt(string s, int x, int y)
{
try
{
Console.SetCursorPosition(origCol+x, origRow+y);
Console.Write(s);
}
catch (ArgumentOutOfRangeException e)
{
Console.Clear();
Console.WriteLine(e.Message);
}
}

Loading DLLs at runtime in C#

I am trying to figure out how you could go about importing and using a .dll at runtime inside a C# application. Using Assembly.LoadFile() I have managed to get my program to load the dll (this part is definitely working as I am able to get the name of the class with ToString()), however I am unable to use the 'Output' method from inside my console application. I am compiling the .dll then moving it into my console's project. Is there an extra step between CreateInstance and then being able to use the methods?
This is the class in my DLL:
namespace DLL
{
using System;
public class Class1
{
public void Output(string s)
{
Console.WriteLine(s);
}
}
}
and here is the application I want to load the DLL
namespace ConsoleApplication1
{
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(#"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
foreach(Type type in DLL.GetExportedTypes())
{
var c = Activator.CreateInstance(type);
c.Output(#"Hello");
}
Console.ReadLine();
}
}
}
Members must be resolvable at compile time to be called directly from C#. Otherwise you must use reflection or dynamic objects.
Reflection
namespace ConsoleApplication1
{
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(#"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
foreach(Type type in DLL.GetExportedTypes())
{
var c = Activator.CreateInstance(type);
type.InvokeMember("Output", BindingFlags.InvokeMethod, null, c, new object[] {#"Hello"});
}
Console.ReadLine();
}
}
}
Dynamic (.NET 4.0)
namespace ConsoleApplication1
{
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(#"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
foreach(Type type in DLL.GetExportedTypes())
{
dynamic c = Activator.CreateInstance(type);
c.Output(#"Hello");
}
Console.ReadLine();
}
}
}
Right now, you're creating an instance of every type defined in the assembly. You only need to create a single instance of Class1 in order to call the method:
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(#"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
var theType = DLL.GetType("DLL.Class1");
var c = Activator.CreateInstance(theType);
var method = theType.GetMethod("Output");
method.Invoke(c, new object[]{#"Hello"});
Console.ReadLine();
}
}
You need to create an instance of the type that expose the Output method:
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(#"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");
var class1Type = DLL.GetType("DLL.Class1");
//Now you can use reflection or dynamic to call the method. I will show you the dynamic way
dynamic c = Activator.CreateInstance(class1Type);
c.Output(#"Hello");
Console.ReadLine();
}
Activator.CreateInstance() returns an object, which doesn't have an Output method.
It looks like you come from dynamic programming languages? C# is definetly not that, and what you are trying to do will be difficult.
Since you are loading a specific dll from a specific location, maybe you just want to add it as a reference to your console application?
If you absolutely want to load the assembly via Assembly.Load, you will have to go via reflection to call any members on c
Something like type.GetMethod("Output").Invoke(c, null); should do it.
foreach (var f in Directory.GetFiles(".", "*.dll"))
Assembly.LoadFrom(f);
That loads all the DLLs present in your executable's folder.
In my case I was trying to use Reflection to find all subclasses of a class, even in other DLLs. This worked, but I'm not sure if it's the best way to do it.
EDIT: I timed it, and it only seems to load them the first time.
Stopwatch stopwatch = new Stopwatch();
for (int i = 0; i < 4; i++)
{
stopwatch.Restart();
foreach (var f in Directory.GetFiles(".", "*.dll"))
Assembly.LoadFrom(f);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
}
Output:
34
0
0
0
So one could potentially run that code before any Reflection searches just in case.
It's not so difficult.
You can inspect the available functions of the loaded object, and if you find the one you're looking for by name, then snoop its expected parms, if any. If it's the call you're trying to find, then call it using the MethodInfo object's Invoke method.
Another option is to simply build your external objects to an interface, and cast the loaded object to that interface. If successful, call the function natively.
This is pretty simple stuff.

Scope Resolution Operator in c# to access global variable?

I have a Program in C++
int x=100; //Global declaration
main()
{
int x=200;
{
int y;
y=x;
cout<<"Inner Block"<<endl;
cout<<x<<endl;
cout<<y<<endl
cout<<::x<<endl;
}
cout<<"Outer Block"<<"\n";
cout<<x<<"\n";
cout<<::x;
}
Output of this program is:
Inner Block
200
200
100
Outer Block
200
100
I want to try similar thing in c# but when I type ::x,i gives me error...
Please help
What I have tried is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CAScopeResolution_Operator
{
class Program
{
static int x = 100;
static void Main(string[] args)
{
int x = 200;
{
int y;
y = x;
Console.WriteLine("Inner Block");
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(Program.x);
}
Console.WriteLine("Outer Block");
Console.WriteLine(x);
Console.WriteLine(Program.x);
Console.ReadLine();
}
}
}
I have declared static x,but I dont think this is the solution to have similar code in c#... Please help
As C# does not deal with global variables as C++ does, the :: has a different meaning. It is about namespaces here, as you can identify each member by the class it belongs to.
So if you have namespaces and/or types that share an identifier but in different namespace, you can identify them using ::-operator.
using colAlias = System.Collections;
namespace System
{
class TestClass
{
static void Main()
{
// Searching the alias:
colAlias::Hashtable test = new colAlias::Hashtable();
// Add items to the table.
test.Add("A", "1");
test.Add("B", "2");
test.Add("C", "3");
foreach (string name in test.Keys)
{
// Searching the global namespace:
global::System.Console.WriteLine(name + " " + test[name]);
}
}
}
}
generates this
A 1
B 2
C 3
See here for MSDN reference.

Categories