All, I'm new to C# and I'm trying to work through a problem that I'm having a hard time understanding.
I'm referencing a library in my code (which I've successfully added to my references). I've also identified the specific namespace within the library to bring in. However, when I initialize an instance of a class within said namespace I'm running into some issues.
The class in question has a constructor (I believe) that has an IntPtr argument. When I'm initializing an instance of the class in my code it's expecting me to provide it with an IntPtr argument, but I don't understand what exactly I should be providing. I know that IntPtr is a pointer to a space in memory, but what that means in my code I'm not sure.
Here is a link to the Library in question: https://github.com/filoe/cscore
The Namespace/Class in reference is in my code below.
using System;
using CSCore.CoreAudioAPI;
namespace EndpointController_POC_v0._1
{
class Program
{
static void Main(string[] args)
{
AudioEndpointVolume endPtCtrl = new AudioEndpointVolume(?);
endPtCtrl.SetMasterVolumeLevelScalar(1, Guid.Empty);
Console.ReadLine();
}
}
}
Related
I want to detect in my C# code whenever the user presses the physical snapshot button in a webcam.
I discovered that the webcam's own software application has a dll (emDLL.dll) that contains various functions, and I used Dependency Walker to know if it includes an exported function that does what I want. And yes, it has one, whose unmangled name is int IsButtonPressed(void)
Reviewing various responses referred to this issue, I managed myself to write the C# code below to test that unmanaged DLL's function:
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest3
{
// EntryPoint is assigned with the mangled name of the exported unmangled function int CEM2800Prop::IsButtonPressed(void)
[DllImport(#"emDLL.dll", EntryPoint = "?IsButtonPressed#CEM2800Prop##QAEHXZ")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int IsButtonPressed();
public static void Main()
{
int Aux;
Aux = IsButtonPressed();
}
}
The problem is that when the code reaches the point when the function is called, appears an exception with the following error:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I need to know what is wrong in my code and if there are some way to call from within my C# code that emDLL.dll function.
Thanks to all.
This is an example console application (it will run fine after adding the Unity NugGet package) that seems to show a bug in Unity:
using System;
using Microsoft.Practices.Unity;
class GC { public static UnityContainer Container = new UnityContainer();}
class Program
{
static void Main(string[] args)
{
GC.Container.RegisterType<MyView>();
var myView = GC.Container.Resolve<MyView>();
Console.ReadLine();
}
}
public class MyClassDesign: MyClass{}
public class MyClass: VMBase<MyClass, MyClassDesign>{}
public abstract class VMBase<TViewModel, TDesignVM> where TDesignVM:TViewModel
{
static VMBase()
{
if (!GC.Container.IsRegistered(typeof(TViewModel)))
GC.Container.RegisterType(typeof (TViewModel), typeof(TDesignVM));
}
}
public class MyView
{
public MyView(MyClass myClass)
{
Console.WriteLine("Bad: "+myClass.GetType().ToString());
Console.WriteLine("Good: "+GC.Container.Resolve<MyClass>().GetType());
}
}
The output is:
Bad: MyClass
Good: MyClassDesign
The resolved type is MyClass. But it should be MyClassDesign. (The static constructor runs prior to MyClass being resolved in the MyView class.)
How can I get Unity to allow me to setup my Mapping in the Static Constructor?
Note: When I changed this setup the UnityContainer with a file (instead of in code) it all works fine. But I would rather not be dependent on an external file for this. (I am making a reusable template that I don't want to have too many dependencies in.)
Why do you want to put the registration logic inside your view model at all? This couples your application code to the container which is never a good idea. Have a look at the concept of Composition roots.
All setup code for the DI container should be placed there.
This isnt really a bug with Unity. The issue is that the static ctor is not run until an instance is requested (at which point unity still does not know about MyClassDesign). Which means that Unity has already started creating an instance of MyClass to fulfill the request. Any subsequent calls to GC.Container.Resolve<MyView>(); will result in the output you expect. As Sebastian Weber suggests, putting all your setup code in a completely seperate location (so your classes are not dependent on a specific DI container) is the best option.
I am working on a project that requires implementing am unmanaged windows DLL. The DLL is used to communicate with a USB device. My code is in C# and WPF.
To initialize the DLL I call a function called:
InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
When calling this function I have to pass a struct called dllInitParams and the Handle that the control is bound to.
I am using DllImport for function pointer as such:
[DllImport("myDll.dll")]
public static extern void InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
Here is my struct:
public struct dllInitParams
{
public UInt16 simp;
public UInt16 simt;
}
All of the above are in a separate class called myDllInterface.cs. Here is how I call the InitTimerDll function from my WPF form:
public IntPtr Handle
{
get { return (new System.Windows.Interop.WindowInteropHelper(this)).Handle; }
}
private void initTime_Click(object sender, RoutedEventArgs e)
{
myDllInterface.dllInitParams initParams = new myDllInterface.dllInitParams();
initParams.simp = 0;
myDllInterface.InitTimerDll(this.Handle.ToInt32(), ref initParams);
}
The first part of the above code explains how I get the handle and the initTime_Click shows how I initialize the struct, call the initTimeDll function by passing the handle and the struct to it. I have copied the dll file in the directory that the code runs in. My code compiles just fine but it creates an error when I click on the initTime button.
Error:
An unhandled exception of type 'System.AccessViolationException' occurred in ProbeCTRL.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Why is this happening?
Without knowing exactly what the InitTimerDll() function does with the 'this' pointer, I would focus on the params structure. Try adding a structure layout markup like the following:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct dllInitParams
{
public UInt16 simp;
public UInt16 simt;
}
Also, double check that your structure is complete and accurate.
I found the problem. The code is fine the problem was the dll file, which was corrupted. A proper copy of the dll file took care of the problem. When using dll in your codes it is quite important to make sure you have accurate information, function calls, data types to passed and so on.
Thanks everyone for your help.
Have a look at the PInvoke tutorial: http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx
as Jim Gomes points out:
[StructLayout(LayoutKind.Sequential)]
or something similar is definitely important.
Also, you're only initializing one of the variables in your struct.
I have written a dll in C#, offering a class for use. The dll is called by a C program that I have written. (It’s a plugin to some program. I have to write the plugin’s code in C, but I want to use the functionality of .NET, therefore the dll).
In the dll, I want to open up a stream and do other stuff that should be persistent between two calls to the dll. That is represented in the following code by the private member Connector.
namespace myCSharpDll
{
// the c++ program calls this methods
public interface IAccess
{
double Initialize();
double Timestep(double time, double[] values);
...
}
// E is the beginning of another program my dll should connect to, therefore the names
public class EAccess : IAccess
{
// EConnector is another class I defined in the same dll
private EConnector Connector;
public double InitializeE()
{
Connector = new EPConnector();
}
public double Timestep(double time, double[] values)
{
return Connector.Connect();
}
When I make a call to InitializeE() and later one to Timestep() the Connector oject points to NULL.
What do I have to do that when I call Timestep() from my C code, that I can access the before created instance of Connector?
I probably search in the wrong direction at all. Any tips are appreciated.
If I am not wrong you want to maintain a single object throughout the use of dll in c. If that is the case try something similar to singleton pattern.
http://en.wikipedia.org/wiki/Singleton_pattern
What singleton emphazises is you create only single object for a class and use it to perform all the work you need. Basically you might need a function that does something like this,
public class EAccess : IAccess
{
private static EConnector Connector
public EConnector getConnector(){
if(Connector == null){
Connector = new EConnector();
}
return Connector;
}
public double Timestep(double time, double[] values)
{
return getConnector().Connect();
}
};
Even though this is not the traditional way of doing things using singleton but I think it still does the work. I may be wrong. Please correct me if I have misunderstood something.
Thanks SLaks for asking for my C/C++ code. That is where the problem was located. It was simpler than I thought. I found the mistake while putting together the code to show you.
I know that C and C++ is not the same, the plugin structure is just a little weird. Most of the code was generated by a wizard. I just had to fill in my code. It's a cpp file, but the code seems to be C. Well, I think that is off topic.
Here it is, I extraced the most important lines.
// the dll is connected via COM, using the type library file that regasm generated
#import "[path]\myCSharpDll.tlb" raw_interfaces_only
using namespace myCSharpDll;
static void OnActivate (IfmDocument, Widget);
//off topic: this are the weird lines the wizard put in my way
#ifdef __cplusplus
extern "C"
#endif /* __cplusplus */
// when the plugin is called by the host program, this function is called
static void OnActivate (IfmDocument pDoc, Widget button)
{
InitializeIntermediate(pDoc);
Timestep1(...);
}
static void InitializeIntermediate(IfmDocument pDoc)
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
IEPAccessPtr pIEPAccess(__uuidof(EPAccess));
double result = -1;
pIEPAccess->InitializeEP (&result);
...
}
static void Timestep1(...)
{
IEPAccessPtr pIEPAccess(__uuidof(EPAccess));
double result = -1.1;
pIEPAccess->Timestep (...);
...
// now I get a wrong result back here, because this call leads to nowhere as
// the connector object in the dll is void
}
I realized that I am requesting a second instance with that line
IEPAccessPtr pIEPAccess(__uuidof(EPAccess));
So I changed that pointer to one single instance and everything is fine. Thanks for your comments!
It looks cool on MSDN:
Specifies that the method is declared, but its implementation is
provided elsewhere.
So I tried it in a console application:
public class Program
{
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
public static extern void Invoke();
static void Main(string[] args)
{
Invoke();
Console.Read();
}
}
Then what should I do now? Where can I provide the implementation of Program.Invoke?
The usage of ForwardRef goes pretty much like this:
consumer.cs
using System;
using System.Runtime.CompilerServices;
class Foo
{
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
static extern void Frob();
static void Main()
{
Frob();
}
}
provider.cs
using System;
using System.Runtime.CompilerServices;
class Foo
{
// Need to declare extern constructor because C# would inject one and break things.
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
public extern Foo();
[MethodImplAttribute(MethodImplOptions.ForwardRef)]
static extern void Main();
static void Frob()
{
Console.WriteLine("Hello!");
}
}
Now the magic sauce. Open a Visual Studio command prompt and type:
csc /target:module provider.cs
csc /target:module consumer.cs
link provider.netmodule consumer.netmodule /entry:Foo.Main /subsystem:console /ltcg
This uses one of the lesser known functionality of the linker where we're linking managed modules together. The linker is able to gel together same-shaped types (they need to have the exact same methods, etc.). ForwardRef is the thing that actually lets you provide implementation elsewhere.
This example is kind of pointless, but you can imagine things getting more interesting if a single method is implemented in a different language (e.g. IL).
My understanding is that ForwardRef acts in the same way as extern, and is intended for guiding the runtime when the language you are using lacks direct support (via extern in C#). As such, the usage should be very similar to the extern modifier, most notably using [DllImport(...)].