|
GDI manages it by substituting the font with something it can render. You wouldn't expect to draw with it on screen anyhow. Oh well. I'm already doing it the Win32 way as we speak...
--
Kein Mitleid Für Die Mehrheit
|
|
|
|
|
I have a problem that is very similar to others that I have seen around the web but no exactly the same. I am trying to call a DLL written in unmanaged C++, from an application written in C#. The C# application will need to pass the DLL function two structs, one with input variables and one for the return variables. I have tried some of the similar solutions but still have not been successful. I have some experience with C# but I am very new to calling DLLs. Any help would be greatly appreciated. Here is my code:
C++:
extern "C"
{
typedef struct
{
unsigned int iSignalCount;
double *dSignal;
unsigned int iFilterCount;
double *dFilter;
} My_Function_Input_Type;
typedef struct
{
unsigned int iDftCount;
double *dDft;
double *dFilteredSignal;
} My_Function_Return_Type;
_declspec(dllexport) void FFT_Convolution(My_Function_Input_Type input, My_Function_Return_Type output);
}
modified on Thursday, October 29, 2009 1:43 PM
|
|
|
|
|
Hi,
you need P/Invoke, which isn't very simple. And having array pointers inside structs makes it even harder.
is the C++ code yours, can you (temporarily) modify it?
I assume the input arrays are instantiated and loaded by managed code, and the arrays in the result are created and loaded by native code? please confirm.
show us what you have so far, and give clear symptoms. I'm not going to explain it all, I'll build on what you have.
And how will the result arrays ever get freed? (it would be much easier if they too could start as managed arrays, hence really be part of the input).
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Thank you for replying...
The C++ code is not mine. All of the array instantiations is done on the C# side.
Here is my C# code:
[StructLayout(LayoutKind.Sequential)]
public struct My_Function_Input_Type
{
public UInt32 iSignalCount;
public Double[] dSignal;
public UInt32 iFilterCount;
public Double[] dFilter;
}
[StructLayout(LayoutKind.Sequential)]
public struct My_Function_Return_Type
{
public UInt32 iDftCount;
public Double[] dDft;
public Double[] dFilteredSignal;
}
[DllImport(@"My_DLL.dll")]
public static extern void My_Funtion(My_Function_Input_Type input, ref My_Function_Return_Type rtrn);
Main()
{
My_Function_Input_Type input = new My_Function_Input_Type();
input.dSignal = ReadFile(Raw_TextBox.Text);
input.iSignalCount = Convert.ToUInt32(input.dSignal.Count());
input.dFilterKernel = ReadFile(Filter_TextBox.Text);
input.iFilterCount = Convert.ToUInt32(input.dFilterKernel.Count());
My_Function_Return_Type rtrn = new My_Function_Return_Type();
rtrn.iDftCount = PowerOfTwo(Convert.ToUInt32(input.dSignal.Count()));
rtrn.dDft = new double[Convert.ToInt32(rtrn.iDftCount)];
rtrn.dFilteredSignal = new double[Convert.ToInt32(rtrn.iDftCount)];
My_Function(input, ref rtrn);
DoSomethingWithOutput(rtrn);
}
This gives me a "Exception of type 'System.ExecutionEngineException' was thrown." error.
Thank you in advance for any guidance you can provide.
|
|
|
|
|
Hi,
CircuitDoc wrote: All of the array instantiations is done on the C# side
that is nice.
I now have several comments:
1. I never had a ExecutionEngineException before. Most often a P/Invoke mistake yields an access violation of some kind.
2. I am not familiar with Array.Count() method; I would use Array.Length. And I would expect Count() to return an integer, so I don't see a need for Convert.ToUInt32() four times.
3. Your second parameter has ref although nothing in the C++ source justifies that. I would throw it out (twice).
4. In C/C++ a double* is a simple pointer to one or several doubles; in C# double[] is the reference to an array, that is not the same as a data pointer. You need to:
- replace all arrays by IntPtr types inside the structs;
- allocate the arrays outside the structs;
- pin or fix each of the arrays so they can't be moved around while native code is running; this takes either the fixed keyword and the unsafe keyword and compiler switch, or, my preference, the GCHandle class. An C# example follows:
public int ArrayHandle() {
int dim=10000;
int[] numbers=new int[dim];
...
GCHandle handle=GCHandle.Alloc(numbers, GCHandleType.Pinned);
int sum=SumArray(handle.AddrOfPinnedObject(), dim);
handle.Free();
return sum;
}
That should get you going. If and when it still fails, please show updated code and symptoms again.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
modified on Tuesday, October 27, 2009 4:02 PM
|
|
|
|
|
Thanks to Luc Pattyn and a little more reasearch on the Web, I solved this using the GCHandle Class.
Here is the updated working code:
public struct MY_Input_Type
{
public UInt32 iSignalCount;
public IntPtr dSignal;
public UInt32 iFilterCount;
public IntPtr dFilterKernel;
}
public struct MY_Return_Type
{
public UInt32 iDftCount;
public IntPtr dDft;
public IntPtr dFilteredSignal;
}
[DllImport(@"MY_DLL.dll")]
public static extern uint PowerOfTwo(uint b);
[DllImport(@"MY_DLL.dll")]
public static extern void FFT_Convolution(MY_Input_Type input, MY_Return_Type rtrn);
public void Start(string rawFile, string filterFile, string outFile)
{
MY_Input_Type input;
MY_Return_Type rtrn;
double[] filterData;
double[] rawData;
double[] returnData;
double[] returnFilter;
filterData = ReadFile(rawFile);
rawData = ReadFile(filterFile);
GCHandle rawHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
GCHandle filterHandle = GCHandle.Alloc(filterData, GCHandleType.Pinned);
input.dSignal = rawHandle.AddrOfPinnedObject();
input.dFilterKernel = filterHandle.AddrOfPinnedObject();
input.iFilterCount = Convert.ToUInt32(filterData.Length);
input.iSignalCount = Convert.ToUInt32(rawData.Length);
rtrn.iDftCount = PowerOfTwo(Convert.ToUInt32(rawData.Length));
returnData = new double[Convert.ToInt32(rtrn.iDftCount)];
returnFilter = new double[Convert.ToInt32(rtrn.iDftCount)];
GCHandle rtrnData = GCHandle.Alloc(returnData, GCHandleType.Pinned);
GCHandle rtrnFilter = GCHandle.Alloc(returnFilter, GCHandleType.Pinned);
rtrn.dDft = rtrnData.AddrOfPinnedObject();
rtrn.dFilteredSignal = rtrnFilter.AddrOfPinnedObject();
FFT_Convolution(input, rtrn);
WriteOutput(returnFilter, returnData, outFile);
rawHandle.Free();
filterHandle.Free();
rtrnData.Free();
rtrnFilter.Free();
}
If anyone sees a way to optimize this code, please let me know. Thanks...
|
|
|
|
|
Hi have a good day
<br />
string mysrt = "Hello {0}";<br />
<br />
Console.WriteLine ("Hello {0}" , "World");<br />
How I can do the above Code With MessageBox.Show ??
thank in advance
P.S:
I don't want to use The String.Replace
I know nothing , I know nothing ...
|
|
|
|
|
Stark DaFixzer wrote: I don't want to use The String.Replace
I don't want to copy the documentation.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Succinct and sarcastic. I like it!
CCC solved so far: 2 (including a Hard One!)
|
|
|
|
|
Console.WriteLine uses String.Format behind the scenes. Pass the normal parameters to String.Format, and show the return value using MessageBox.Show
|
|
|
|
|
Stark DaFixzer wrote: I don't want to use The String.Replace
Why? This is exactly what Console.Writline does.
CCC solved so far: 2 (including a Hard One!)
|
|
|
|
|
use like this ...
MessageBox.Show(String.Format(mystr , "world"));
|
|
|
|
|
Thank you so much ,
That is exactly what I need ,,
I know nothing , I know nothing ...
|
|
|
|
|
Most welcome budd...
|
|
|
|
|
MessageBox.Show(string.Format("Hello {0}" , "World"));
|
|
|
|
|
Thank you ,
I know nothing , I know nothing ...
|
|
|
|
|
Hi
I was trying to create a windows application that sends emails. Recently I installed windows 7 on my machine and added the IIS from the windows add/remove components. When my application tries to send email with smtp.send() method, I am always getting SMTP host was not specified. I read in the internet that windows 7 does not come with SMTP server so I installed SMTP server from hMailServer.com and tried.
Now I am getting SMTP authentication fails. Does anyone have have problems with windows 7.
Any Ideas please.
Thanks.
--
http://ashakthi.blogspot.com
http://kids-articles.blogspot.com
|
|
|
|
|
This has nothing to do with Windows 7. You need to consult the documentation on the STMP server you're using and properly set the thing up. You also need to provide credentials in your code to login to the SMTP so it can send your email.
|
|
|
|
|
Hi,
In the runtime, when I need to make an SQL connection to my local DB, it gives an error like below:
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connection. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
It is weird because I'm not using a remote database. My DB file is under the root directory of the program.
Can anybody help?
note: I'm pretty sure that my connection string is correct
|
|
|
|
|
How do you connect to your SQL-Server? TCP/IP, NamedPipes, SharedMemory?
|
|
|
|
|
well, I'm not sure, I just added a DB in my project, created some tables, and now trying to reach those tables as
SqlConnection conn = null;
conn = new SqlConnection("Data Source=|DataDirectory|\\MyDatabase.sfd");
conn.Open(); <---- this is where the error points
|
|
|
|
|
Is the server running? Check all the services. Check if the user id and password you are providing has access to the database.
It's not necessary to be so stupid, either, but people manage it. - Christian Graus, 2009 AD
|
|
|
|
|
I looked up the connection string from the app.config file and it did not have any connection parameters like id or password
"Data Source=|DataDirectory|\\MyDatabase.sfd"
I'm also not sure how to check these related services, as I explained to Covean, I added a DB to my project and I think it must have been running by default
:/
|
|
|
|
|
Maybe this article helps: http://support.microsoft.com/default.aspx?scid=kb;EN-US;914277
|
|
|
|
|
Use a SQLCeConnection [^] instead of a SQLConnection . You're connecting to a SQL CE database (*.sdf), not a SQL Server database (*.mdb). The latter one indeed requires a server
I are Troll
|
|
|
|