<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.microsoft.co.il/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Just code - Tamir Khason : Microsoft, Interop</title><link>http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Microsoft/Interop/default.aspx</link><description>Tags: Microsoft, Interop</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>New year – new blog or how to migrate Community Server to any other engine, supports XML-RPC</title><link>http://blogs.microsoft.co.il/blogs/tamir/archive/2009/01/01/new-year-new-blog-or-how-to-migrate-community-server-to-any-other-engine-supports-xml-rpc.aspx</link><pubDate>Fri, 02 Jan 2009 02:33:04 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:205248</guid><dc:creator>Tamir Khason</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Please update your bookmarks, because the new url of this blog is &lt;a href="http://khason.net/"&gt;http://khason.net/&lt;/a&gt; (you have not update RSS feeds, it will be done automatically). Why I did it? Why I decided to go to “stand-alone”… Well. there are some reasons. Generally, I do not want to explain all those here, but trust me, there are some. The main reason is, that there is no responsible person in charge for this blog platform in Microsoft Israel. This why, if your blog is popular and you have a respect to your blog visitors, you cannot host it here… Take a look into new comments notifications in my inbox. Would you answer your readers with such “small amount” of SPAM and capcha, that cannot be fixed already for three years in this platform? This how my inbox looks like for last three years. So now, you should not ask me, why I not answered your email or comments. Aren’t you? :)&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Capture" border="0" alt="Capture" src="http://blogs.microsoft.co.il/blogs/tamir/Capture_1D7350A7.jpg" width="354" height="397" /&gt; &lt;/p&gt;  &lt;p&gt;Currently, all comments in this blog are disabled, so if you want to comment, please use new url of posts (this will appear shortly in the beginning of each post). Also, this post will not be syndicated in RSS.&lt;/p&gt;  &lt;p&gt;So, this post is the last. I loved this platform, and loved people started it. But, unfortunately, it seemed, that bloggers community is not important enough for new platform managers. &lt;/p&gt;  &lt;p&gt;Also, If you want to learn &lt;a target="_blank" href="http://khason.net/dev/how-to-migrate-from-cs2007-to-wordpress-movable-type-or-any-other-blog-engine-supports-xml-rpc-with-c/"&gt;how to use C# and XML-RCP to migrate from CS2007, used in this platform, visit my new home&lt;/a&gt; :)&lt;/p&gt;  &lt;p&gt;Have a great year and, as always, be good people. This post marked with all possible tags automatically. Sorry.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=205248" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/soft/default.aspx">soft</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/blogging+tools/default.aspx">blogging tools</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/tutorial/default.aspx">tutorial</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WPF+crossbow/default.aspx">WPF crossbow</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/source/default.aspx">source</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Mobile/default.aspx">Mobile</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/help/default.aspx">help</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Windows+Gadgets/default.aspx">Windows Gadgets</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/promo/default.aspx">promo</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Vista/default.aspx">Vista</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/thoughts/default.aspx">thoughts</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/tools/default.aspx">tools</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/events/default.aspx">events</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/demos/default.aspx">demos</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WPF_2F00_E/default.aspx">WPF/E</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/download/default.aspx">download</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/jobs/default.aspx">jobs</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/VSTS/default.aspx">VSTS</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Web/default.aspx">Web</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Accessibility/default.aspx">Accessibility</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Blogging+rules/default.aspx">Blogging rules</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/blogging+general/default.aspx">blogging general</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/fun/default.aspx">fun</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Vista+Battery+Saver/default.aspx">Vista Battery Saver</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/SkyDrive/default.aspx">SkyDrive</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Windows+Live+Writer/default.aspx">Windows Live Writer</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Windows+Live/default.aspx">Windows Live</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Dell/default.aspx">Dell</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DevAcademy2/default.aspx">DevAcademy2</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WPF+quiz/default.aspx">WPF quiz</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/x64/default.aspx">x64</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/SVG/default.aspx">SVG</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/XPS/default.aspx">XPS</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/TechedIsrael2008/default.aspx">TechedIsrael2008</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/teched/default.aspx">teched</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/PLINQ/default.aspx">PLINQ</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Micro+Framework/default.aspx">Micro Framework</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/SAP/default.aspx">SAP</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/XLINQ/default.aspx">XLINQ</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DirectX/default.aspx">DirectX</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Work+process/default.aspx">Work process</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Linux/default.aspx">Linux</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Mono/default.aspx">Mono</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DevAcademy3/default.aspx">DevAcademy3</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Math/default.aspx">Math</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/GIS/default.aspx">GIS</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Algorithms/default.aspx">Algorithms</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/TECH/default.aspx">TECH</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Windows+7/default.aspx">Windows 7</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Charity/default.aspx">Charity</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/OFFTOPIC/default.aspx">OFFTOPIC</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Hardware/default.aspx">Hardware</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Interop/default.aspx">Interop</category></item><item><title>Capturing and streaming sound by using DirectSound with C#</title><link>http://blogs.microsoft.co.il/blogs/tamir/archive/2008/12/25/capturing-and-streaming-sound-by-using-directsound-with-c.aspx</link><pubDate>Thu, 25 Dec 2008 23:48:20 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:201052</guid><dc:creator>Tamir Khason</dc:creator><slash:comments>3</slash:comments><description>&lt;h3&gt;[This blog was migrated. You will not be able to comment here.&lt;br /&gt;The new URL of this post is &lt;a href="http://khason.net/blog/capturing-and-streaming-sound-by-using-directsound-with-c/"&gt;http://khason.net/blog/capturing-and-streaming-sound-by-using-directsound-with-c/&lt;/a&gt;]&lt;/h3&gt;&lt;hr /&gt;&lt;p&gt;I already wrote a little about &lt;a href="http://blogs.microsoft.co.il/blogs/tamir/archive/2008/02/17/sound-tone-and-dtmf-generation-by-using-managed-directsound-and-c-and-sine-tone-detection-with-pure-managed-goertzel-algorithm-implementation.aspx"&gt;managed way to use DirectX DirectSound&lt;/a&gt;. Today we’ll speak about how to get sound from your microphone or any other DirectSound capturing device (such as &lt;a href="http://blogs.microsoft.co.il/blogs/tamir/archive/2008/12/12/reading-and-decoding-rds-radio-data-system-in-c.aspx"&gt;FM receiver&lt;/a&gt;) and stream it out to your PC speakers and any other DirectSound Output device. So, let’s start creating our first echo service by using managed DirectX.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/tamir/image_13541F81.png" width="225" height="229" /&gt; &lt;/p&gt;  &lt;p&gt;First of all we should decide what Wave format we want to use for capturing and recording. So, let’s choose anything reasonable :)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;var format = new WaveFormat {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SamplesPerSecond = 96000,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BitsPerSample = 16,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Channels = 2,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FormatTag = WaveFormatTag.Pcm      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, we should calculate block align and average byte per second value for this format. I’m wondering why it cannot be done automatically…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8));     &lt;br /&gt;format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Next step is to set the size of two buffers – one for input and other for output. Generally those buffers are circular, and capturing one should be twice bigger, then output. Why? Because we choose two channels to use. Also, we should decide about chunk size of the buffer, we want to signal when filled.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;_dwNotifySize = Math.Max(4096, format.AverageBytesPerSecond / 8);     &lt;br /&gt;_dwNotifySize -= _dwNotifySize % format.BlockAlign;      &lt;br /&gt;_dwCaptureBufferSize = NUM_BUFFERS * _dwNotifySize;      &lt;br /&gt;_dwOutputBufferSize = NUM_BUFFERS * _dwNotifySize / 2;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Next step is to create CaptureBufferDescriptor and actual capturing buffer. We’ll enumerate all devices and choose one, satisfies given string (captureDescriptor) – for example “Mic” :)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;var cap = default(Capture);     &lt;br /&gt;var cdc = new CaptureDevicesCollection();      &lt;br /&gt;for (int i = 0; i &amp;lt; cdc.Count; i++) {      &lt;br /&gt;&amp;#160;&amp;#160; if (cdc[i].Description.ToLower().Contains(captureDescriptor.ToLower())) {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cap = new Capture(cdc[i].DriverGuid);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break;      &lt;br /&gt;&amp;#160;&amp;#160; }      &lt;br /&gt;}      &lt;br /&gt;var capDesc = new CaptureBufferDescription {      &lt;br /&gt;&amp;#160;&amp;#160; Format = format,      &lt;br /&gt;&amp;#160;&amp;#160; BufferBytes = _dwCaptureBufferSize      &lt;br /&gt;};      &lt;br /&gt;_dwCapBuffer = new CaptureBuffer(capDesc, cap);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then we’ll create output device and buffer. To simplify program, we will use default speakers to output, however, you can choose output device the same way we did for capturing. Also, because DirectSound uses any window as it’s message pump, we have to use SetCooperativeLevel method. In my case (windowless application), I’ll use desktop window as message broker. This why you will have to add Windows.Forms as reference for your project, even if it console application. Also, do not forget to set GlobalFocus value to True, if you want to play echo, even if desktop window is not focused.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;var dev = new Device();     &lt;br /&gt;dev.SetCooperativeLevel(Native.GetDesktopWindow(), CooperativeLevel.Priority); &lt;/p&gt;    &lt;p&gt;var devDesc = new BufferDescription {     &lt;br /&gt;&amp;#160;&amp;#160; BufferBytes = _dwOutputBufferSize,      &lt;br /&gt;&amp;#160;&amp;#160; Format = format,      &lt;br /&gt;&amp;#160;&amp;#160; DeferLocation = true,      &lt;br /&gt;&amp;#160;&amp;#160; GlobalFocus = true      &lt;br /&gt;};      &lt;br /&gt;_dwDevBuffer = new SecondaryBuffer(devDesc, dev);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, we will subscribe to buffer notifications and set autoResetEvent to be fired when it filled up.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;var _resetEvent = new AutoResetEvent(false);     &lt;br /&gt;var _notify = new Notify(_dwCapBuffer);      &lt;br /&gt;//half&amp;amp;half      &lt;br /&gt;var bpn1 = new BufferPositionNotify();      &lt;br /&gt;bpn1.Offset = _dwCapBuffer.Caps.BufferBytes / 2 - 1;      &lt;br /&gt;bpn1.EventNotifyHandle = _resetEvent.SafeWaitHandle.DangerousGetHandle();      &lt;br /&gt;var bpn2 = new BufferPositionNotify();      &lt;br /&gt;bpn2.Offset = _dwCapBuffer.Caps.BufferBytes - 1;      &lt;br /&gt;bpn2.EventNotifyHandle = _resetEvent.SafeWaitHandle.DangerousGetHandle(); &lt;/p&gt;    &lt;p&gt;_notify.SetNotificationPositions(new BufferPositionNotify[] { bpn1, bpn2 });&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Almost done, the only thing we should do is to fire worker thread to take care on messages&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;int offset = 0;     &lt;br /&gt;_dwCaptureThread = new Thread((ThreadStart)delegate {      &lt;br /&gt;&amp;#160;&amp;#160; _dwCapBuffer.Start(true); &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160; while (IsReady) {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _resetEvent.WaitOne();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var read = _dwCapBuffer.Read(offset, typeof(byte), LockFlag.None, _dwOutputBufferSize);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _dwDevBuffer.Write(0, read, LockFlag.EntireBuffer);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; offset = (offset + _dwOutputBufferSize) % _dwCaptureBufferSize;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _dwDevBuffer.SetCurrentPosition(0);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _dwDevBuffer.Play(0, BufferPlayFlags.Default);      &lt;br /&gt;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160; _dwCapBuffer.Stop();      &lt;br /&gt;});      &lt;br /&gt;_dwCaptureThread.Start();&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That’s it. Compile and run. Now if you’ll speak, you can hear your echo from PC speakers. &lt;/p&gt;  &lt;p&gt;Merry Christmas for whom concerns and be good people – do not scare your co-workers with strange sounds – be polite and make the volume lower :) &lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=201052" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/tutorial/default.aspx">tutorial</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/source/default.aspx">source</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DirectX/default.aspx">DirectX</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Work+process/default.aspx">Work process</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Hardware/default.aspx">Hardware</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Interop/default.aspx">Interop</category></item><item><title>How to P/Invoke VarArgs (variable arguments) in C#? ... or hidden junk in CLR</title><link>http://blogs.microsoft.co.il/blogs/tamir/archive/2008/11/19/how-to-p-invoke-varargs-variable-arguments-in-c-or-hidden-junk-in-clr.aspx</link><pubDate>Wed, 19 Nov 2008 11:44:10 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:170664</guid><dc:creator>Tamir Khason</dc:creator><slash:comments>1</slash:comments><description>&lt;h3&gt;[This blog was migrated. You will not be able to comment here.&lt;br /&gt;The new URL of this post is &lt;a href="http://khason.net/blog/how-to-pinvoke-varargs-variable-arguments-in-c-or-hidden-junk-in-clr/"&gt;http://khason.net/blog/how-to-pinvoke-varargs-variable-arguments-in-c-or-hidden-junk-in-clr/&lt;/a&gt;]&lt;/h3&gt;&lt;hr /&gt;&lt;p&gt;Recently I &lt;a href="http://blogs.microsoft.co.il/blogs/tamir/archive/2008/10/20/p-invoke-cheat-sheet.aspx"&gt;wrote a cheat sheet for pinvoking in .NET&lt;/a&gt;. Shortly after I got a question in comments about how to deal with variable arguments, when it&amp;#39;s more, then one parameter. Also what to do if those arguments are heterogeneous? &lt;/p&gt; &lt;p&gt;Let&amp;#39;s say, that we have following method in C:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;int VarSum(int nargs, ...){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; va_list argp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; va_start( argp, nargs );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int sum = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for( int i = 0 ; i &amp;lt; nargs; i++ ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int arg = va_arg( argp, int );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum += arg;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; va_end( argp );  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sum;&lt;br /&gt;}&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;We can expose this method to C# as following:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;[System.Runtime.InteropServices.DllImportAttribute(&amp;quot;unmanaged.dll&amp;quot;, EntryPoint = &amp;quot;VarSum&amp;quot;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static extern int VarSum(int nargs,int arg1); &lt;p&gt;[System.Runtime.InteropServices.DllImportAttribute(&amp;quot;unmanaged.dll&amp;quot;, EntryPoint = &amp;quot;VarSum&amp;quot;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static extern int VarSum(int nargs,int arg1,int arg2);&lt;/p&gt; &lt;p&gt;[System.Runtime.InteropServices.DllImportAttribute(&amp;quot;unmanaged.dll&amp;quot;, EntryPoint = &amp;quot;VarSum&amp;quot;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static extern int VarSum(int nargs,int arg1,int arg2,int arg3);&lt;/p&gt; &lt;p&gt;etc...&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;And it will work. However, if you&amp;#39;ll try to expose it as int array, marshaller will fail to understand how to align things&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;[System.Runtime.InteropServices.DllImportAttribute(&amp;quot;unmanaged.dll&amp;quot;, EntryPoint = &amp;quot;VarSum&amp;quot;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static extern int VarSum(int nargs,int[] arg);&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This in spite of the fact, that this method will work properly with another signature&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;int ArrSum(int* nargs) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int sum = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for( int i = 0 ; i &amp;lt; 2; i++ ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum += nargs[i];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sum;&lt;br /&gt;}&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So what to do? The &lt;u&gt;official&lt;/u&gt; answer is - &lt;strong&gt;you have nothing to do, rather then override all possibilities&lt;/strong&gt;. This is very bad and absolutely not flexible. So, there is small class in C#, named ArgIterator. This one is similar to params object[], but knows to marshal into varargs. The problem is, that you have no way to add things inside. It&amp;#39;s &amp;quot;kind-of-read-only&amp;quot;. &lt;/p&gt; &lt;p&gt;Let&amp;#39;s look into reflected version of ArgIterator. We&amp;#39;ll see there something, named &lt;strong&gt;__arglist and __refvalue&lt;/strong&gt;. OMG, isn&amp;#39;t it good old stuff similar to &amp;quot;__declspec(dllexport) int _stdcall&amp;quot; etc.? It is! But can we use it in C#? We can! Just sign your method as Cdecl and you have working signature for &amp;quot;...&amp;quot;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;[System.Runtime.InteropServices.DllImportAttribute(&amp;quot;unmanaged.dll&amp;quot;, EntryPoint = &amp;quot;VarSum&amp;quot;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CallingConvention=System.Runtime.InteropServices.CallingConvention.Cdecl)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static extern int VarSum(int nargs, __arglist);&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Yes, looks strange, and absolutely not CLR compliant. However, this is the only way to expose varargs to CLR via P/Invoke. How to use it? Simple:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;c = VarSum(2, __arglist(5, 10));&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Have a nice day and be good people. Also, my question to Microsoft is why this stuff is not in MSDN and we, as developers, have no way to get rid of it. &lt;/p&gt; &lt;p&gt;Is not it very good practices to use non-compliant methods? Give us another way to do it!&lt;br /&gt;Is not it very good practices to use variable arguments in unmanaged method signatures? So why you want dynamic types in C# 4?&lt;/p&gt; &lt;p&gt;&lt;a href="http://cid-4e39ecd492e4eec1.skydrive.live.com/self.aspx/Public/VarArgsMarshaller.zip%20"&gt;Source code for this article&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=170664" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/tutorial/default.aspx">tutorial</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/source/default.aspx">source</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Work+process/default.aspx">Work process</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/tamir/archive/tags/Interop/default.aspx">Interop</category></item></channel></rss>