I am using a Java webservice. I'm consuming it with an Excel function which I made using c# and excel-dna. The problem is that everytime I call the function add I get (#valeur).
This my c# code source:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExcelDna.Integration;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace MyLibrary
{
public class Class1
{
[ExcelFunction(Description = "adds two terms")]
public static int add(int a, int b)
{
ServiceReference1.ServerImplClient client =
new ServiceReference1.ServerImplClient();
return client.addition(a, b);
}
}
}
Service Reference has been included and the dna and xll files also.
Approach debugging this step by step.
To debug an Excel DNA method from Visual Studio, you need to:
bring up your Excel; make sure that the XLL that is loaded is the one in the bin directory
in Visual studio "attach" to the excel process (tools->attach to process or Ctrl-Alt-p)
put a breakpoint at the start of your function (if the correct XLL is loaded the breakpoint will be a filled circle; if it isn't then the loaded XLL is a different one)
If you then make a call to your function and it doesn't hit the breakpoint, you may be passing in the wrong parameter types (side note: all numeric values in Excel are doubles - you can always have object parameters and check the arguments in your function).
If it does hit your function then you can step through your client code in the normal way.
Related
So I have two dlls, Algorithms.dll and Data_Structures.dll (I made these from projects I found on GitHub). Using the browse feature I have managed to add both of the DLL files as references to my Visual Studio 2017 console project. The problem is I can't do anything else with them. Whenever I try to reference something within either file, it simply cannot be found. The only thing that is recognized is the namespace, but nothing inside of that.
What do I need to do to get VS to find the classes these DLLs contain so I can use them? I am aware I need to use Algorithms.Sorting for the example but I can't call anything so I used this as an example.
P.S. If you need more info, please ask. I'm not sure what's relevant to this issue.
EDIT: Ok, it was misleading to have that kind of example. Corrected but please read the question.
EDIT: I tried this on Monodevelop and get the same issue. Maybe it's not the IDE that's the problem?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Algorithms.Sorting; // Error, Sorting cannot be found, and neither can the file container Sorting
using Data_Structures; //Perfectly ok, can find the namespace
namespace CS_HW2_Testing_App
{
class Program
{
static void Main(string[] args)
{
// I'd like to call MergeSort and so forth here. What am I missing?!
}
}
}
Here's the top piece of the file containing MergeSort if it helps
using System;
using System.Collections.Generic;
using Algorithms.Common;
namespace Algorithms.Sorting
{
public static class MergeSorter
{
//
// Public merge-sort API
public static List<T> MergeSort<T>(this List<T> collection, Comparer<T> comparer = null)
{
comparer = comparer ?? Comparer<T>.Default;
return InternalMergeSort(collection, 0, collection.Count - 1, comparer);
}
...
In the first code block, you're importing the wrong namespace: using Algorithms.MergeSort should be using Algorithms.Sorting. Then you can use MergeSorter.MergeSort<T>(...) in your code!
You need to reference the namespace not the class.
using Algorithms.Sorting; //instead of using Algorithms.MergeSort;
Plus make sure the classes are public
Sorry for the title. I don't know how to describe this problem shortly.
My problem is that I have a class-library which has references to other (third party) DLLs.
I need to use this class-library in another project, so I obviously added the .dll of my class-library to my main-project.
When I start my main-project, there's alway an error which says, that a reference (dll) in my class-library cannot be found.
If I add the whole class-library as a project to my projectmap in visual studio and then reference the whole project, this error doesn't occur.
I really don't want to add the whole class-library as a project to every "host"-project I make.
Has anyone an idea why this error occurs when the .dll of the class-library is added, but not when the whole project of the class-library is added as reference?
There must be a solution to get this working even if I don't add the whole library-project as reference. Otherwise it wouldn't make any sense to make a class library, right?
By the way: My class-library contains third-party dlls and the local copy property of the third-party dll is set to true.
Thanks in advance!
Edit:
My goal is to really make the class-library portable, even though it contains third-party libraries. I want to give only the .dll to another pc and use it without adding the whole class-library project every time.
The error is because you're not copying the dll's on the second project, you added a reference to your dll so it get's copied, but not the dll's referenced by your dll, so there are missing libraries.
Or you redistribute the dependencys with your dll or you can embedd the dll's inside your dll as resources and then intercept the assembly load and provide it through a resource: http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
EDIT: IN order to do it inside a dll you need to use an static class and call an static initializer BEFORE using any of the classes which are dependant on other libraries.
Here is an example setup:
-A library called LibraryB which supplies a simple class like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryB
{
public class ReferencedClass
{
public int GetIt()
{
return 5;
}
}
}
-A library called LibraryA which references LibraryB and supplies two classes, the initializer and the real class:
Initializer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace LibraryA
{
public static class Initializer
{
public static void Init()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
if (!args.Name.StartsWith("LibraryB"))
return null;
return Assembly.Load(LibraryA.Properties.Resources.LibraryB);
};
}
}
}
Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryA
{
public class RealClass
{
public int DoIt()
{
LibraryB.ReferencedClass cl = new LibraryB.ReferencedClass();
return cl.GetIt();
}
}
}
The LibraryA also has the LibraryB.dll compiled library embedded as a resource.
-A project called Test which only references LibraryA:
using LibraryA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Initializer.Init();
RealClass c = new RealClass();
Console.WriteLine("From LibraryA: " + c.DoIt());
Console.ReadKey();
}
}
}
If you set-up everithing right and you execute it it will work, remember that if you are doing through visual studio, vs will copy the dll's so to do a real test after compiling all copy the exe and LibraryA and execute, it will work without LibraryB and LibraryB is being used from LibraryA.
I have a .r file which fetches data from database, performs some calculation and write back to a new table in database.
I am trying to execute the .r file from C# using visual studio 2010.
The C# code is mentioned below.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RDotNet;
using RDotNet.Devices;
using RDotNet.Internals;
namespace EmbeddAssembly
{
class Program
{
static void Main(string[] args)
{
string rhome = System.Environment.GetEnvironmentVariable("R_HOME");
if (string.IsNullOrEmpty(rhome))
rhome = #"C:\Program Files\R\R-2.14.1";
System.Environment.SetEnvironmentVariable("R_HOME", rhome);
System.Environment.SetEnvironmentVariable("PATH", System.Environment.GetEnvironmentVariable("PATH") + ";" + rhome + #"binx64");
// Set the folder in which R.dll locates.
//REngine.SetDllDirectory(#"C:Program FilesRR-2.12.0bini386″);
REngine.SetDllDirectory(#"C:\Program Files\R\R-2.14.1\bin\x64");
// REngine e = REngine.CreateInstance("test", new[] { "" });
using (REngine engine = REngine.CreateInstance("RDotNet", new[] { "-q" })) // quiet mode
{
foreach (string path in engine.EagerEvaluate(".libPaths()").AsCharacter())
{
Console.WriteLine(path);
}
engine.Evaluate(".libPaths(C:\\Program Files\\R\\R-2.14.1\\library)");
engine.Evaluate("source(C:\\Users\\..\\Documents\\Visual Studio 2010\\Projects\\EmbeddAssembly\\multi.r)");
Console.ReadLine();
}
}
}
}
I am not getting any error but it is not calling the .r file.
The code in r file works fine because I am able to retrive data and write into the table. However on calling that from C# it is not performing any action.
You are missing character delimitors around arguments to the R functions called. Also, avoid using backslashes when passing strings to R.NET's Evaluate. You may need to end up having quadruple backslashes (or even more if using regular expressions) to get things to work.
You should use something like:
engine.Evaluate(".libPaths('C:/Program Files/R/R-2.14.1/library')");
engine.Evaluate("source('C:/Users/Documents/Visual Studio 2010/Projects/EmbeddAssembly/multi.r')");
It seems you are using a very old version of R.NET; I strongly advise you to use R.NET.Community on NuGet. I know there is an R.NET nuget feed still up too, but this appears not maintained anymore. Also, FYI, R.NET latest reference documentation is now on a GitHub page
To avoid requiring a Dll be registered for all users of a spreadsheet, I'm trying to use late binding so that users do not need to add a reference to the Dll.
I've created the Dll in C# with Visual Studio, and even though I've included "using RGiesecke.DllExport;" and used DllExport on a function to return an object containing the functions I need to access in VBA, I still get the error "Run-time error '453': Can't Find DLL entry point CreateDotNetObject in C:\temp\MyFunctions.dll."
The DLL code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Data;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Client;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections;
using System.Collections.ObjectModel;
using System.Threading;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework;
using Microsoft.TeamFoundation.Common;
using Microsoft.VisualBasic;
using System.Diagnostics;
using RGiesecke.DllExport;
namespace MyFunctions
{
public interface IMyFunctions
{
string GetWorkItemLinkList(string WIIDs);
}
[CLSCompliant(true), ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
public class MyFunctions : IMyFunctions
{
TfsConfigurationServer server;
WorkItemStore store;
private void TFSconnect()
{
//Code to connect
}
[CLSCompliant(true), ComVisible(true), Description("GetWorkItemLink func")]
public string GetWorkItemLink(int WIID)
{
TFSconnect();
//Code to build return string "message"
return message;
}
[CLSCompliant(true), ComVisible(true), Description("GetWorkItemLinkList func")]
public string GetWorkItemLinkList(string WIIDs)
{
TFSconnect();
//Code to build return string "returnStr"
return returnStr;
}
}
static class UnmanagedExports
{
[DllExport]
[return: MarshalAs(UnmanagedType.IDispatch)]
static Object CreateDotNetObject()
{
return new MyFunctions();
}
}
}
and the declaration in VBA is as follows:
Private Declare Function CreateDotNetObject Lib "c:\temp\MyFunctions.dll" () As Object
But when I try to instantiate an object, I get the error I mentioned above.
Sub test()
Dim o As Object
Set o = CreateDotNetObject()
End Sub
This is my first time attempting to use custom dll functions in Excel without adding a reference in the VBA. The functions do work if I add a reference (early binding), but the DLL is not going to be propogated to everyone who uses the spreadsheet, and I need it to not crash when they run normal functions.
EDIT: Additional info. I just noticed that in addition to the DLL, when I build the solution in Visual Studio I also get an " Object FileLibrary" and an "Exports Library File". When I register the DLL is there anything I should be doing with either the .exp or .lib?
Thanks,
Mike
I was building the solution with the Platform Target in the class library properties set to "Any PC", which apparently does not allow exports. When I switch it to "x86" it totally works.
I've got big problem with invoking method from DLL in Oracle Forms 6i. DLL has been written in
C#, and it is code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OnlineFPCommon;
using System.Windows.Forms;
namespace TestNamespace
{
public class TestClass
{
public static void testMethod()
{
MessageBox.Show("testMethod");
}
}
}
I try to invoke it using Oracle Forms code:
testlib_lhandle := Ora_Ffi.Load_library('C:\libdir\','test.dll');
getresult_fhandle := ora_ffi.register_function(testlib_lhandle,'testMethod');
but the second line, when I try to register function fails. Why? How Can I properly invoke that function?
register_function requires a dll entry point and you cannot generate that in managed code.
You can write a C++/CLi wrapper DLL to have native entry points for your managed code but if you are just starting from scratch then why not just write a plain native dll.