sing System;
using System.Text;
using System.Runtime.InteropServices;
namespace LCAudioDll
{
#region 檔案結構引數定義
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public unsafe struct _Fileinfo
{
public int Duration; //play Duration
public int SampleRate; //audio samplerate
public int BitRate; //audio bitrate
}
#endregion
#region 音頻結構引數定義
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public unsafe struct _WaveInInfo
{
public int Index; //The first soundcard is index 0,the second soundcard is index 1, and so on.
public int name; //soundcard's name which is selected.
public int Formats; //(unuse)
public int Channels; //(unuse)
}
#endregion
#region 混音器結構引數定義
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public unsafe struct _MuxInfo
{
public char name; //Mixer Name
}
#endregion
#region 動態庫結構引數定義
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public unsafe struct _PlayParam
{
/// Windows視窗句柄,如果不為NULL,執行緒將事件訊息發送到此視窗
public UInt32 hWnd;
/// 音頻流優先級,1優先級最低,255優先級最高,音頻終端優先播放優先級高的音頻。
public Int32 Priority;
/// 組播組號,表示執行緒向那個組發送音頻資料,當播放方式是單播或廣播是,此引數無意義。
public Int32 MultiGroup;
/// 播放方式,單播,組播和廣播
public Int32 CastMode;
/// IP地址,當為播放方式單播是指的是目標IP地址,為組播和廣播時,表示使用的本地網路介面
public UInt32 IP;
///播放音量
public Int32 Volume;
///播放音調
public Int32 Tone;
/// 高音頻率
public Int32 Treble;
/// 低音頻率
public Int32 Bass;
/// 高音放大因子
public Int32 Treble_En;
/// 低音放大因子
public Int32 Bass_En;
/// 音頻資料源,0表示資料源為檔案,1表示資料源為聲卡輸入(Line in 或 mic輸入)
public short SourceType;
/// 聲卡采樣開關變數
public short OptionByte;
/// 聲卡ID號,僅在SourcType = 1時有效,表示采用哪個聲卡的輸入。
public Int32 DeviceID;
/// 混音器名字,表示混音器的那個輸入通道最終被采樣。不同的聲卡有不同的混音器名字。
public fixed byte MuxName[64];
/// 通道,采樣的通道數
public Int32 nChannels;
/// 音源為聲卡輸入時的采樣頻率
public Int32 nSamplesPerSec;
/// 音頻檔案的長度,僅SourcType=0時有效
public Int32 AudioBufferLength;
/// 音頻資料存盤地址
public IntPtr AudioBuf;
/// 私有資料陣列,用戶不能修改里面的資料。
public fixed Int32 PrivateData[128];
}
#endregion
#region 動態褲函式匯入
public unsafe class LCAudioThrDll
{
private const string LCAudioThrDllName = "LCAudioThrDll.dll";
//(1) Initialize the _PlayParam structure.
[DllImport(LCAudioThrDllName, EntryPoint = "lc_init")]
public extern static int Lc_Init(string filename, _PlayParam* pParam);
//(2) Start playing audio data
[DllImport(LCAudioThrDllName, EntryPoint = "lc_play")]
public static extern int Lc_Play(_PlayParam* pParam);
//(3) Stop playing audio data
[DllImport(LCAudioThrDllName, EntryPoint = "lc_stop")]
public static extern int Lc_Stop(_PlayParam* pParam);
//(4) Pause playback audio data
[DllImport(LCAudioThrDllName, EntryPoint = "lc_pause")]
public static extern int Lc_Pause(_PlayParam* pParam);
//(5) Continue playing audio data
[DllImport(LCAudioThrDllName, EntryPoint = "lc_continue")]
public static extern int Lc_Continue(_PlayParam* pParam);
//(6) Specify play time point
[DllImport(LCAudioThrDllName, EntryPoint = "lc_seek")]
public static extern int Lc_Seek(_PlayParam* pParam, Int32 time);
//(7) Wait for the play to finish
[DllImport(LCAudioThrDllName, EntryPoint = "lc_wait")]
public extern static int Lc_Wait(_PlayParam* pParam);
//(8) Dynamically adjust the volume
[DllImport(LCAudioThrDllName, EntryPoint = "lc_set_volume")]
public static extern int Lc_Set_Volume(_PlayParam* pParam, Int32 Volue);
//(9) Get the played time
[DllImport(LCAudioThrDllName, EntryPoint = "lc_get_playtime")]
public static extern int Lc_Get_PlayTime(_PlayParam* pParam);
//(10) Get play status
[DllImport(LCAudioThrDllName, EntryPoint = "lc_get_playstatus")]
public extern static int Lc_Get_PlayStatus(_PlayParam* pParam);
//(11) Get the total play time of the current file
[DllImport(LCAudioThrDllName, EntryPoint = "lc_get_duration")]
public static extern int Lc_Get_Duration(_PlayParam* pParam);
//(12) Get the information of the specified file
[DllImport(LCAudioThrDllName, EntryPoint = "lc_get_fileinfo")]
unsafe public static extern int Lc_Get_FileInfo(string filename, ref _Fileinfo myfileinfo);
//(13) Get the information of the sound card
[DllImport(LCAudioThrDllName, EntryPoint = "lc_rec_devinfo")]
public extern static int Lc_Rec_DevInfo(_WaveInInfo* Info, ref int Number);
//(14) Get the information of the sound mixer
[DllImport(LCAudioThrDllName, EntryPoint = "lc_rec_muxinfo")]
public extern static int Lc_Rec_MuxInfo(_MuxInfo* Info, ref int Number);
//(15) Get the version information of dynamic library
[DllImport(LCAudioThrDllName, EntryPoint = "lc_get_version")]
public extern static int Lc_Get_Version();
//(16) Get the last error message
[DllImport(LCAudioThrDllName, EntryPoint = "lc_getlasterror")]
public extern static int Lc_GetLastError(_PlayParam* pParam);
//(17) Start to record audio data
[DllImport(LCAudioThrDllName, EntryPoint = "lc_record_start")]
public static extern int Lc_Record_Start(_PlayParam* pParam, string filename);
//(18) Stop to record audio data
[DllImport(LCAudioThrDllName, EntryPoint = "lc_record_stop")]
public static extern int Lc_Record_Stop(_PlayParam* pParam);
//(19) Query recording status
[DllImport(LCAudioThrDllName, EntryPoint = "lc_record_status")]
public static extern int Lc_Record_Status(_PlayParam* pParam);
//(20) Allocate memory
[DllImport(LCAudioThrDllName, EntryPoint = "lc_play_getmem")]
public static extern _PlayParam* Lc_Play_GetMem();
//(21) Free memory
[DllImport(LCAudioThrDllName, EntryPoint = "lc_play_freemem")]
public static extern int Lc_Play_FreeMem(_PlayParam* Plm);
//(22) Add unicast device
[DllImport(LCAudioThrDllName, EntryPoint = "lc_addip")]
public static extern int Lc_AddIP(_PlayParam* pParam, uint ip);
//(23) Delete unicast device
[DllImport(LCAudioThrDllName, EntryPoint = "lc_delip")]
public static extern int Lc_DelIP(_PlayParam* pParam, uint ip);
//(24) Input audio data of WAV to the dynamic library
[DllImport(LCAudioThrDllName, EntryPoint = "lc_inputdata")]
public static extern int Lc_InputData(_PlayParam* pParam, byte[] buf, int datalen);
//(25) Input audio data of MP3 to the dynamic library
[DllImport(LCAudioThrDllName, EntryPoint = "lc_inputdata_mp3")]
public static extern int Lc_InputData_Mp3(_PlayParam* pParam, byte[] buf, int datalen);
}
#endregion
}
上面是C# 例子,如何改為VB。net
我自個改了,好象呼叫不成功,
Option Explicit On
Imports System
Imports System.Text
Imports System.Runtime.InteropServices
Module Module1
'定義網路通信方式
Public Const cUnicast = 0 '單播
Public Const cMulticast = 1 '組播
Public Const cBroadcast = 2 '廣播
Public Const AUDIO_TYPE_UNKNOWN = 0
Public Const AUDIO_TYPE_MP3 = 1
Public Const AUDIO_TYPE_WAV = 2
Public Const AUDIO_TYPE_WMA = 3
Public Const SCR_TYPE_FILE = 0 '資料來源是檔案
Public Const SCR_TYPE_AUDIOCARD = 1 '資料來源是聲卡
Public Const SCR_TYPE_BUFFER = 2 '資料來源是記憶體快取
Public Const SCR_TYPE_STREAM = 3 '資料來源是資料流'V2.0.3.0
'定義函式回傳值
Public Const R_OK = 0 '成功
Public Const ERR_PARAM = -1 '引數錯誤
Public Const ERR_OPT = -2 '函式執行錯誤
Public Const ERR_SOCKET = -3 'socket操作失敗
Public Const ERR_CODEC = -4 '初始化編解碼器失敗。
'Windows 訊息定義
Public Const WM_USER = &H400
'public const WM_MSG_EXCEPTION (WM_USER+100)
Public Const WM_MSG_COMPLETED = (WM_USER + 101)
Public Const WM_MSG_PAUSE = (WM_USER + 102)
Public Const WM_MSG_CONTINUE = (WM_USER + 103)
Public Const WM_MSG_AUDIOPOWER = (WM_USER + 104)
'Public Const WM_MSG_DATA = (WM_USER + 9901)
#Region "檔案結構引數定義"
Public Structure FileInfo
Public Duration As Long '播放時長
Public SampleRate As Long '采樣率
Public BitRate As Long '位元率
End Structure
#End Region
#Region "音頻結構 聲卡資訊結構"
Public Structure WaveInInfo
Public Index As Long '輸入通道的序號
Public name As Long '名字
Public Formats As Long '支持的格式
Public Channels As Long '通道數 2為立體聲輸入。
End Structure
#End Region
#Region "混音器名稱"
Public Structure MuxInfo
<VBFixedArray(63)> Public name() As Byte '名字
End Structure
#End Region
#Region "執行緒播放結構"
' <StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)>
Public Structure PlayParam
Public hWnd As Long 'Windows視窗句柄,如果不為NULL,執行緒將事件訊息發送到此視窗主視窗的句柄
Public Priority As Long '音頻流優先級 1最低 255最高
Public MultiGroup As Long '組播組號,表示執行緒向那個組發送音頻資料,當播放方式是單播或廣播是,此引數無意義。
Public CastMode As Long '播放方式,單播,組播和廣播
Public IP As Long 'ip,如果是廣播和多播,此引數是源網卡的IP,如果此地址為0,則由系統決定使用哪個網卡,如果是單播,這是個目標設備的ip地址。
Public Volume As Long '播放音量取值0~100
Public Tone As Long '音調
Public Treble As Long
uj5u.com熱心網友回復:
好多,不愿意動彈。一條路是就這么改,,,另一條更簡單一些,你用C#封裝一個DLL呼叫就可以了。。。
看了一下,就這么幾種,自己該一下也不難:
_PlayParam* pParam:先試一下直接傳入結構體,byval就可以。不行的話用intprt,再用marshal把結構體傳進去。。應該沒這么麻煩
ref int這種就byref int就可以了
陣列的和上面的結構體一樣處理就行
uj5u.com熱心網友回復:
C#封裝DLL更不會了。現在的關鍵是因為結構體在記憶體中估計沒對好。用VB6寫的能正常呼叫,用.net 死活對不全。uj5u.com熱心網友回復:
謝謝,可以的話,能不能幫我寫個?[email protected] 我發資料下面是DLL廠家提供的說明, 我用VB。net 主要是不知道如何對位。分配記憶體,并保存記憶體位置不變??
說明:_PlayParam結構變數應該是一個分配在堆記憶體上的變數,并保證在整個播放程序記憶體有效,且呼叫lc_play函式后,不能修改結構的內容。對于使用C#開發的用戶,還應該保證此結構變數在播放程序中記憶體位置不能改變。建議C#用戶使用提供的lc_play_getmem,和lc_play_freemem為_PlayParam結構變數分配和釋放記憶體。
如果用戶自己申請的記憶體,請將記憶體清空,防止記憶體內的垃圾資料造成兼容性問題。
uj5u.com熱心網友回復:
新建c#winform類別庫專案:
把廠家給的初始類別庫代碼粘貼覆寫上去。刪掉原來的設計代碼:

點擊生成。
vb.net專案中,參考成功生成的類別庫:

如上圖的LCAudioDll.dll。
ok了,最后效果

uj5u.com熱心網友回復:
謝謝,試過了,vs2010 VS2019提示“未知故障” 然后就沒了。還有一次提示別的,具體忘了。我晚上再詳細試下uj5u.com熱心網友回復:
好象是不安全的代碼只有在UNLSafeg下出現uj5u.com熱心網友回復:
[DllImport(LCAudioThrDllName, EntryPoint = "lc_play_getmem")]public static extern _PlayParam* Lc_Play_GetMem();
就是分配一個記憶體,只要你不會收再重新申請,那它就滿足他所說的條件。注意把這個指標宣告為與播放程序相同的生存期,免得被垃圾回收了。
這樣,其實不一定非得用指標,_PlayParam* 可以用intptr來保存,使用時也用intptr。。
你這個指望大家給你改肯定不行,沒有dll沒法測驗。你先把那個lc_getlaseterror宣告對了。然后按照你呼叫的程序,逐步除錯直到這個API回傳的值表明其它API呼叫正確,你的播放內核部分也就做完了。
uj5u.com熱心網友回復:
你要明白,C#保留了使用*的方法,但實際上不用*也可以用指標,指標是一個指向記憶體地址的變數,歸根結底它就是一個變數而已。C#即使不使用不安全代碼也可以使用指標,只不過是被封裝過的指標,在IL解釋之后,它還是那個指向記憶體地址的變數,.NET只是包裝了一下,附加了其它資訊而已,而運行時會決議這些資訊。C#與VB.NET只有少數不同的地方,VB.NET無法使用的特性也非常少,并且VB.NET完全可以操作指標,即使不使用marshal也可以得到自己的函式地址,可以得到陣列地址,字串地址…………如果使用封裝好的marshal類,那么就能更簡單的獲取和使用這些東西。這些都不是問題,但是VB.NET中就是沒有*,用Intptr就可以了,甚至可以用Int64,integer這都可以。如果想深入理解指標,你可以用vc++寫一段代碼,宣告幾個變數,試一下* & 之類的運算子。并不一定要在代碼中輸出地址,可以 用一些除錯工具,反編譯一下,看看資料在哪,指著存在哪個地址里,如果能夠理解ASM那就更好了,能夠看到編譯后的代碼讓CPU如何通過指標操作資料,如何通過變數操作資料,對應起來看看就全都明白了。指標不是多么難多么難,至少看看這些東西之后簡單的指標操作還是可以理解的非常好的。
歸根結底,編程語言就是一種工具,里面的各種東西也都是工具,使用哪種工具時,有興趣就可以把它拆了看看內部構造,玩不壞的,還能學不少東西。例如你這個DLL,宣告有問題,出在哪個變數里面,到底是指標還是結構,到底是byval還是byref完全可以把這個DLL反編譯一下,瀏覽一下它的原型,最多看一下對引數的操作程序,非常容易就把呼叫方式確定下來了。
uj5u.com熱心網友回復:
謝謝版主,兩天試下來,感覺問題還是出在結構體大小不一樣的原因,在c#中用SIZEof函式,取得結構體大小為0x0000000C 即12位元組,而同樣結構體在VB.net中卻有24位元組,代碼如下vb.net
結構體定義:
Public Structure FileInfo
Public Duration As Long '播放時長
Public SampleRate As Long '采樣率
Public BitRate As Long '位元率
End Structure
表單加載中運行:
Dim afileinfo As New FileInfo
aaa = System.Runtime.InteropServices.Marshal.SizeOf(afileinfo)
MsgBox(Len(afileinfo), vbExclamation, "錯誤")
aaa為24 按這個應是正確,LONG是8位元組 但在C#中:[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct _Fileinfo
{
public int Duration; //play Duration
public int SampleRate; //audio samplerate
public int BitRate; //audio bitrate
}
private int DelayNum = 0; //Current count of delay
_Fileinfo abc;
DelayNum = sizeof (_Fileinfo); DelayNum 卻=12 按C#提示 INt32,應是對應LONG 也是8位元組?
uj5u.com熱心網友回復:
另附上DLL廠家提供的檔案及示例: 鏈接:https://pan.baidu.com/s/1Y5kAqrfN93ULhObXgbiAoQ提取碼:2m6d
問下,這里不能有償發布嗎?若真有朋友幫完成,表達一下心意也應該啊。
uj5u.com熱心網友回復:
專案要改成不安全代碼uj5u.com熱心網友回復:
可以嘗試拿人家c#編譯好的程式用ilspy等工具反編譯,查看的反編譯代碼改成vb. netuj5u.com熱心網友回復:
辣就是你粗心哈。。sizeof得到的結果是一樣的才對uj5u.com熱心網友回復:
我有這個水平,也就不用求助了。。。。。。。水平也就盤底一點了。
uj5u.com熱心網友回復:
很感謝你的耐心回復。
不是粗心,只是水平低,學習中,畢竟我的主要作業是硬體的程式,現在為了測驗硬體,不得不硬著頭皮。不然硬體沒法除錯,交付。所以才想著花點錢(硬體程式對方給了1K,都兩個月沒,一直沒除錯不出來,對不起人家,所以才想著有人幫,分點開發費快速搞搞定)
uj5u.com熱心網友回復:
官方沒有測驗代碼提供給客戶端開發人員嗎
uj5u.com熱心網友回復:
另外廠家也就這個樣子,只有一個會c#的,花了幾天也沒搞定。而客戶那邊原來的軟體都是VB.net 要接入他們程式才能測驗,才現在這個局面。有空嗎,有空的話,幫我寫個示例吧。uj5u.com熱心網友回復:
58627564我的QQ號uj5u.com熱心網友回復:
VB.NET的long對應C#的long,64位帶符號整數VB.NET的Integer對應C#的int,32位帶符號整數
uj5u.com熱心網友回復:
還有,C#結構體有個屬性[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]你翻譯了嗎?我沒看到VB里有這句話uj5u.com熱心網友回復:
66666666666666666666666uj5u.com熱心網友回復:
看看學習學習下

uj5u.com熱心網友回復:
C# 中的int是 int32的簡寫, 對應的int64就是long,int16就是short;例子中的 public int Index,vb.net中你要寫為public index as integer
還有最基本的名字定義你都搞錯了,MuxInfo在C#中前面有個_(下劃線)。還有很多你都沒翻譯。
翻這個要耐心。C#能寫出來的,vb.net都有對應的語法。這個真心不難。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/70726.html
標籤:VB.NET
下一篇:問下各位C#針對AD域的一些操作
