|
What exactly are you trying to do?
C# is one of many languages that target the CLR. Managed C++ (targets the CLR and has equal access to .NET assemblies, as well as native APIs) is another. But VC++ (unmanaged) is entirely different.
When you expose your DSP as a COM control (which it already is by nature), you're merely using it in your C# project.
I really don't understand what your problem is. If your DSP is written in VC++, then what are you trying to do in managed code (i.e., C#). If you're trying to use it, you declare the interfaces (as you have) and have to be able to instantiate the object. If your DSP has a typelib, you can use tlbimp.exe to generate an RCW (Runtime Callable Wrapper) or in Visual Studio .NET select Add Reference, click on the COM tab and either find your typelib in the list (if registered properly) or click the Browse button to find it. Either way will generate an interop library (the RCW) then you just use it.
Software Design Engineer
Developer Division Sustained Engineering, Microsoft
My Articles
|
|
|
|
|
What I'm trying to do is this:
I have an application that I've written in C# using DirectSound. It allows for PLAYBACK of a pre-recorded .wav file, RECORDING of a .wav file and STREAMING of audio input from the soundcard.
Now, I would like to be able to process this audio input by sending the audio data through a DSP routine.
My DSP routines are coded in C++.
My signal flow would be as follows:
*input* -> DSP routine -> *output*
The input and output have already been implemented in C# .NET.
The DSP routine has been coded in C++. I could write it in C# if I absolutely HAD to, but I'm trying to avoid that.
What is the best way to get this working?
|
|
|
|
|
Depends - is the DSP a COM object or exported functions (perhaps even a class - but that gets more complicated; see the CallingConvention.ThisCall for details - and you'll need to implement an exported class factory function).
If it's COM, declare your RCW (don't forget all the attributes: ComImportAttribute , GuidAttribute , etc.), or use tlbimp.exe or VS.NET's Add Reference if you're COM server has a typelib (or you have a detached typelib).
If you're using exported functions, you'll need to use P/Invoke (see DllImportAttribute ) to call the functions. With CallingConvention.ThisCall , you declare your functions with an extra parameter (the first parameter!) that is an IntPtr , which is a handle to your object. You should also define and export a class factory function, as well as a destruction function to tear-down the object.
See a previous reply I wrote for more details about ThisCall : http://www.codeproject.com/script/comments/forums.asp?msg=771919&forumid=1649#xx771919xx[^].
Software Design Engineer
Developer Division Sustained Engineering, Microsoft
My Articles
|
|
|
|
|
What are you trying to accomplish? If it is the part of the DSP processing that is interfacing to the hardware I would be inclined to leave it C++. If it an application to help control the DPS process that might be worth writing in C#.
It is all about a sensible system framework. If your C++ libraries are tangled together in pointers it might not be feasible at all to put into C#. If on the other hand system is segmented clearly and easily broken appart then that will help interop a lot.
|
|
|
|
|
Hey all -
Really quickly, how can I dynamically change a property with reflection? For example, if I have a class:
class Foo{<br />
public bool Enabled{...}<br />
}
I can dynamically load the class with the following:
Type t = System.GetType("David.Demo.Foo");<br />
Thanks much,
*->>Always working on my game, teach me
*->>something new.
cout << "dav1d\n";
|
|
|
|
|
afronaut wrote:
Type t = System.GetType("David.Demo.Foo");
// how can I set Enabled to false?
PropertyInfo prop = t.GetProperty("Enabled");<br />
<br />
prop.SetValue(f, false, null);
Charlie
if(!curlies){ return; }
|
|
|
|
|
Thank you Charles.
*->>Always working on my game, teach me
*->>something new.
cout << "dav1d\n";
|
|
|
|
|
Hello,
I wrote a program for a PocketPc with these two methods (Invoke from the user32.dll). Unfortunately it seems that the .NET CF does not support these methods, because i always get a MethodMissingException when i execute it on the emulator.
Can anybody help me with an workaround so i can use these two methods??
regards.
patrick
|
|
|
|
|
I believe those functions are defined in coredll.dll (not user32.dll) on Windows CE.
Charlie
if(!curlies){ return; }
|
|
|
|
|
This would be too good to be true. I thought now i functions because now with your hint the MethodMissingException does not occur again. But when i execute now my program with the emulator, nothing happens..?? But when i defined a normal empty project this code will work. The code fragment look as follows: (probably you know what went wrong here - i have to say slowly i' ll get depressed..)
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
namespace SmartDeviceApplication1
{
class Test
{
static AutoResetEvent evt;
static int count = 5;
static void Main(string[] args)
{
if (args.Length > 0)
{
try
{
count = int.Parse(args[0]);
}
catch (Exception e)
{
e.ToString();
}
}
evt = new AutoResetEvent(false);
Timer t = new Timer(new TimerCallback(TimerCallback), null, 0, 5000);
evt.WaitOne();
}
static void TimerCallback(object state)
{
Console.WriteLine("Enumerating windows at {0:t}...", DateTime.Now);
string title = new string('\0', 260);
int ret = GetWindowText(GetForegroundWindow(), title, 260);
if (ret != 0)
System.Console.WriteLine(title.Substring(0, ret));
}
[DllImport("coredll.dll", CharSet=CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, [Out] string title,
int maxCount);
[DllImport("coredll.dll")]
private static extern IntPtr GetForegroundWindow();
}
}
Hopefully you can help mne?!
Regards
pat
|
|
|
|
|
The code looks as follows:
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
namespace SmartDeviceApplication1
{
class Test
{
static AutoResetEvent evt;
static int count = 5;
static void Main(string[] args)
{
if (args.Length > 0)
{
try
{
count = int.Parse(args[0]);
}
catch (Exception e)
{
e.ToString();
}
}
evt = new AutoResetEvent(false);
Timer t = new Timer(new TimerCallback(TimerCallback), null, 0, 5000);
evt.WaitOne();
}
static void TimerCallback(object state)
{
Console.WriteLine("Enumerating windows at {0:t}...", DateTime.Now);
string title = new string('\0', 260);
int ret = GetWindowText(GetForegroundWindow(), title, 260);
if (ret != 0)
System.Console.WriteLine(title.Substring(0, ret));
}
[DllImport("coredll.dll", CharSet=CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, [Out] string title,
int maxCount);
[DllImport("coredll.dll")]
private static extern IntPtr GetForegroundWindow();
}
}
Do you know why this program does anyway not execute correctly on the PocketPc-Emulator?
Regards
pat
|
|
|
|
|
Hello,
I have 2 forms and l want to be able to copy text inputs from one form to the other form. In Visual Basic this was very easy to do. e.g. txtStudentID.Text = frmNewStudent.txtNewStudentID.text.
But i am not sure how to do this in C#.
Can any one tell me.
Thanks in advance,
Steve
|
|
|
|
|
if your TextBox variables are public and not private, then you should be able to do the same things that you did in VB. If you go to the .cs file for the form you should see the TextBox variables defined at the top of the form.
As an alternative, you could make some properties that get and set the data for the other form. This is a more object oriented approach, but not always the best for every application.
Steve Maier, MCSD MCAD
|
|
|
|
|
This is object-oriented development. You need to ensure that objects can access easy other. In this case, make sure that one form can access another, either by passing a variable to a method (perhaps the constructor), assigning a property, or have some intermediary that can access both form objects.
Now, Steve was talking about encapsulation and that is a good idea. Exposing the actual TextBox es to outside code is not (almost never is) a good idea. Remember that those TextBox es have a lot more properties that could be abused.
So, you could simply encapsulate the Text property on your form class (remember that the property would be defined on your form class and not Form , so you may have to cast to your type depending on how one form accesses another):
public string StudentID
{
get { return txtStudentID.Text; }
set { txtStudentID.Text = value; }
} If you don't want this publicly accessible and the forms are not derivative of each other, you can use the internal access modifier, which means that any code within that particular assembly (.NET 2.0 defines an attribute that grants other assemblies that you specify access to internals as well) can access that property (like public only for that assembly, but private to other assemblies).
Software Design Engineer
Developer Division Sustained Engineering, Microsoft
My Articles
|
|
|
|
|
Hello,
Thanks for you reply.
I think l will do it the way that you said.
Just another question, l am creating a small database application for a small library system. I have 2 tables books and students.
The properties of students are: StudentID, Name, Address, Email. I have never done a database application using c#. Just on the student table, how can l make that oop, for example adding, updating and deleting.
I find it easy to do it the vb way.
Any example programs or tutorials.
Many thanks in advance.
Steve
|
|
|
|
|
From the IDE bring up the help files / Index tab.
In the index search for SQLDataAdapter
In the list of help topics is samples. This also exposes the various methods you can use for accessing a database. Access is much much easier than it ever was.
This signature left intentionally blank
|
|
|
|
|
I have been working on a class that will automate an instance of internet explorer based on a script file. The script file will be generated by a non-MFC win32 application written in c++. This application will then need to access my automation classes (could be as simple as starting an executable and passing a file name as argument). I have the basics of my class written and working in managed c++ and c#. The c# code is by far the cleanest looking, and the yet-to-be-done unmanaged c++ will be the ugliest for sure. I am hoping to get advice as to which language and what project type to use.
unmanaged c++ is most familiar (but I really dont want to do this), and I would likely create a .dll, or possibly even a static library.
managed c++ is fairly familiar, but I am not sure what type of project I would use
c# I am new to, but like what I have seen so far. I am leaning toward this, but am not sure if I can access a c# library from unmanaged code, if it should be a console application (I would need to hide the console window), a windows application with no visible window, or possibly a service.
The overall goal is to call some code with an automation script, and this code will take it from there. At this point there is no need for any communication back to the calling application, but it would be nice to have this option left open.
Thank You
|
|
|
|
|
I did something similar in a project for my last job. There were two approaches that we took. The first was to expose the .Net (C#) object with a COM interface so that unmanaged code could use the objects like a normal COM object. The second way is to compile your unmanaged code to include the managed extensions. Then you can just create a new variable of the class type that is in the C# DLL that you make and just use it.
I prefer the second method, but there are a few things that you have to do to be able to do this. I only have VS 2005 installed here now, so this is from memory and a small test that I did here.
- Turn on the managed extensions in the project. This is probably in Configuration Proerties labeled something like "Common Language runtime support"
- Add the following code to your stdafx.h or similar file.
#using < mscorlib.dll >
using namespace System;
using namespace System::Runtime::InteropServices;
- Add the reference to your C# DLL to the unmanged project
- Create a manged variable using code like this:
gcroot< ClassLibrary1::Class1* > c = new ClassLibrary1::Class1();
int t=c->MyProperty;
CString buff;
buff.Format("data = %d",t);
MessageBox(buff);
c->ShowIt();
- Use the class instance using a ->
Using this method you can make the C# library just be a class library project and call the classes from it in your unmanaged code.
Steve Maier, MCSD MCAD
|
|
|
|
|
I should have added the following information:
Our current unmanaged application runs, and needs to continue to run on systems without the .NET framework. I planned on doing a test at the time the new functionality is required to see if the framework is installed, and if not just displaying a message box. I guess this leads me more toward you first solution. I have some limited familiarity with COM-ATL so I could probably work that into our existing code. How would I go about exposing my c# object with a COM interface?
Thank You,
|
|
|
|
|
I have found this article...I should have googled before replying
Thank You
http://www.csharphelp.com/archives/archive190.html
|
|
|
|
|
That is definately a good start. You might also want to put a GUID Attribute above your class definition. Then it will look just like other COM objects.
[GuidAttribute("9ED54F84-A89D-4fcd-A854-44251E925F09")]
class SampleClass{
} I have not played with the idea before, but it might be that if you do this then you might be able to use the fact of the object not initializing to tell you that the framework is not there or that there is something not installed right.
Steve Maier, MCSD MCAD
|
|
|
|
|
I could even go with something like this
http://www.codeproject.com/dotnet/bridge.asp
would be nice to avoid COM altogether
|
|
|
|
|
I use a web application config file in my usercontrol, then I put it in one web application. But the config file can't read from the web application. How do it?
|
|
|
|
|
You do not need a config file just for your usercontrol. Remove it, and place the settings inside of the application config file.
my blog
|
|
|
|
|
Hi~~
I have a problem transfer byte array from directshow filter to C# application.
I made simple directshow filter using C++. that filter has a interface to communication outside application. like this..
DECLARE_INTERFACE_(IGetCurrentData, IUnknown)
{
STDMETHOD(Get_Current_Media) (THIS_
BYTE** pData
) PURE;
STDMETHOD(Get_Current_Media_Legnth) (THIS_
long& length
) PURE;
};
I also declare interface in C# application to communicate with filter(C++ Dll) like this..
[ComVisible(true), ComImport,
Guid("CCB4EF12-C1CC-43a4-82EF-7886C0F39EB1"),
InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
public interface IGetCurrentData
{
[PreserveSig]
int Get_Current_Media([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]out byte[]ar);
[PreserveSig]
int Get_Current_Media_Legnth(out long length);
}
I use this sentence to use C# interface.
byte[] pData;
Get_Current_Media(out pData);
but I meet an exception during runtime. I think datatype is not match. How can I solve this problem?
|
|
|
|
|