用GSM模块发中文短讯,必须以PDU包的形式发送。我将它写成了Dll,直接调用SMSEncode函数即可得到追后的编码。现将原码公开:
unit EnCodeCompnent;interfaceuses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;    function SMSEncode(s:WideString;Result_Code:pchar):Bool;Stdcall;export;
    function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;Stdcall;export;
    function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;stdcall;export;
    function ConvertPhoneNum(strNum:string):string;
    function Transposition(instr:pchar;Result_str:pchar):Bool;stdcall;export;//将一个字符串两两交换位置
    { Public declarations }implementation
function SMSEncode(s:WideString;Result_Code:pchar):Bool;
var
  i,len:Integer;
  cur:Integer;
  t,temp:String;
begin
if length(s)>0 then
  begin
    len:=Length(s);
    i:=1;
    while i<=len do
      begin
        cur:=ord(s[i]);
        //BCD convert
        FmtStr(t,'%4.4X',[cur]);
        temp:=temp+t;
        inc(i);
      end;
    StrCopy(Result_Code,pchar(temp));
    Result:=true;
  end
else
  Result:=false;
end;function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;
var
  str:string;
  i:integer;
  temp:string;
  A_PWideChar:array[0..300] of widechar;
  R_String:string;
  A_integer:integer;
begin
  str:=string(Input_Code);
  R_String:='';
  if length(str)<=0 then
    begin
      Result:=false;
      exit;
    end;
  i:=0;
  while i<length(str) do
    begin
      temp:=copy(str,i+1,4);
      A_integer:=strtoint('$'+temp);
      move(A_integer,A_PWideChar[i div 4],sizeof(A_PWideChar[i div 4]));
      inc(i,4);
    end;
  A_PWideChar[length(str) div 4]:=#0;
  R_String:=WideCharToString(@A_PWideChar);
  StrCopy(Result_Str,pchar(R_String));
  Result:=true;
end;
function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;
const
  lenSmsInfo='00';
  firstOctet='11';
  TPMessageReference='00';
  TypeOfAddress='91';
  TpId='00';
  TpDcs='08';//"00" is 7 bit encode "08" is 8 bit encode;
  TPValidityPeriod='AA';//aa is 4 day
var
  DestPhoneNum:string;
  AddressLength:string;
  TpUserData:string;
  TPUserDataLength:string;
  temp:WideString;
  Tmp_Pchar:pchar;
  Rlt_str:string;
begin
  if (DestNumber='') or (Content='') then
    begin
      Result:=false;
      exit;
    end
  else
    begin
      DestPhoneNum:=ConvertPhoneNum(DestNumber);
      AddressLength:=format('%2.2X',[length(DestNumber)]);
      temp:=Content;
      Tmp_Pchar:=StrAlloc(1000);
      if SMSEncode(temp,Tmp_Pchar) then
        TpUserData:=string(Tmp_Pchar);
      if TpDcs='08' then
        TPUserDataLength:=format('%2.2X',[length(TpUserData) div 2])
      else
        TPUserDataLength:=format('%2.2X',[((length(TpUserData) div 2)*8) div 7]);
      Rlt_str:=lenSmsInfo
              +firstOctet
              +TPMessageReference
              +AddressLength
              +TypeOfAddress
              +DestPhoneNum
              +TpId
              +TpDcs
              +TPValidityPeriod
              +TPUserDataLength
              +TpUserData;//TpUserData have to Encoded;
      StrCopy(Result_String,pchar(Rlt_str));
      Result:=true;
     end;
end;function ConvertPhoneNum(strNum:string):string;
var
i:integer;
str:string;
A_Pchar:pchar;
begin
  str:=strNum;
  i:=length(str);
  if odd(i) then
    begin
      str:=str+'F';
      A_Pchar:=StrAlloc(40);
      if Transposition(pchar(str),A_pchar) then
        result:=string(A_Pchar)
      else
        result:='Null';
    end
  else
    begin
      A_Pchar:=StrAlloc(40);
      if Transposition(pchar(str),A_pchar) then
        result:=string(A_Pchar)
      else
        result:='Null';
    end;
end;function Transposition(instr:pchar;Result_str:pchar):Bool;
var
  i:integer;
  temp:string;
  destStr:string;
  In_String:string;
begin
if length(instr)>0 then
  begin
    destStr:='';
    In_String:=string(instr);
    setlength(In_String,length(In_String));
    i:=1;
    while i<length(In_String) do
      begin
        temp:=In_String[i+1]+In_String[i];
        destStr:=destStr+temp;
        inc(i,2);
      end;
    StrCopy(Result_Str,pchar(destStr));
    result:=true;
  end
else
  begin
    result:=false;
  end;
end;
end.

解决方案 »

  1.   

    {===============================================================} 
    { 函数  : RESULTSTRING = HexToBin(HEXSTRING) 
    { 目的   : 把十六进制字符串转换为二进制字符串   

    {===============================================================} 
    { 函数  : RESULTINTEGER = HexCharToInt(HEXCHAR) 
    { 目的   : 转换一个十六进制字符为整数
    {===============================================================} 
    { 函数  : RESULTSTRING = HexCharToBin(HEXCHAR) 
    { 目的   : 转换一个十六进制字符为二进制字符串
    {===============================================================} 
    { 函数  : RESULTINTEGER = Pow(BASE,POWER) 
    { 目的   : 指数函数
    {===============================================================} 
    { 函数  : RESULTINTEGER = BinStrToInt(BINSTRING) 
    { 目的   : 把二进制字符串转换为整数
    {===============================================================} 
    { 函数  : RESULTSTRING = DecodeSMS7Bit (PDUSTRING) 
    { 目的   : 解码一个7-bit SMS (GSM 03.38) 为ASCII码 
    {===============================================================}
    { 函数  :  RESULTSTRING = ReverseStr (SOURCESTRING)
    { 目的   : 反转一个字符串
    {===============================================================}
    {===============================================================}
    { 函数  :  RESULTSTRING = UniCode2Gb (SOURCESTRING)
    { 目的   : 将UniCode字符串转换为GB
    {===============================================================}
    {===============================================================}
    { 函数  :  RESULTSTRING = GB2UniCode (SOURCESTRING)
    { 目的   : 将GB字符串转换为UniCode
    {===============================================================}unit BinHexTools;
    interface function HexToBin(HexNr : String): String; 
    function HexCharToInt(HexToken : char): Integer; 
    function HexCharToBin(HexToken : char): String; 
    function pow(base, power: integer): integer; 
    function BinStrToInt(BinStr : String) : Integer; 
    function DecodeSMS7Bit(PDU : String): String; 
    function ReverseStr(SourceStr : String) : String; 
    function GB2UniCode(GB:string): String;
    function UniCode2GB(S : String): String;implementation uses sysutils, dialogs; 
    function HexCharToInt(HexToken : char):Integer; 
    begin 
      //if HexToken>#97 then HexToken:=Chr(Ord(HexToken)-32); 
      { 将小写字母转换成大写 }   Result:=0;   if (HexToken>#47) and (HexToken<#58) then       { chars 0....9 } 
         Result:=Ord(HexToken)-48 
      else if (HexToken>#64) and (HexToken<#71) then  { chars A....F } 
         Result:=Ord(HexToken)-65 + 10; 
    end; 
    function HexCharToBin(HexToken : char): string; 
    var DivLeft : integer; 
    begin 
        DivLeft:=HexCharToInt(HexToken);   { first HexChar->Int } 
        Result:=''; 
                                           { Use reverse dividing } 
        repeat                             { Trick; divide by 2 } 
          if Odd(DivLeft) then             { result = odd ? then bit = 1 } 
            Result:='1'+Result             { result = even ? then bit = 0 } 
          else 
            Result:='0'+Result;       DivLeft:=DivLeft div 2;       { keep dividing till 0 left and length = 4 } 
        until (DivLeft=0) and (length(Result)=4);      { 1 token = nibble = 4 bits } 
    end; 
    function HexToBin(HexNr : string): string; 
    { only stringsize is limit of binnr } 
    var Counter : integer; 
    begin 
      Result:='';   for Counter:=1 to length(HexNr) do 
        Result:=Result+HexCharToBin(HexNr[Counter]); 
    end; 
    function pow(base, power: integer): integer; //指数base^power
    var counter : integer; 
    begin 
      Result:=1;   for counter:=1 to power do 
        Result:=Result*base; 
    end; 
    function BinStrToInt(BinStr : string) : integer; 
    var counter : integer; 
    begin 
      if length(BinStr)>16 then 
        raise ERangeError.Create(#13+BinStr+#13+ 
                '不是一个有效的16Bit二进制单元'+#13);   Result:=0;   for counter:=1 to length(BinStr) do 
          if BinStr[Counter]='1' then 
            Result:=Result+pow(2,length(BinStr)-counter); 
    end; 
    function DecodeSMS7Bit(PDU : string):string; 
    var OctetStr : string; 
        OctetBin : string; 
        Charbin  : string; 
        PrevOctet: string; 
        Counter  : integer; 
        Counter2 : integer; 
    begin 
      PrevOctet:=''; 
      Result:='';   for Counter:=1 to length(PDU) do 
        begin 
          if length(PrevOctet)>=7 then     { if 7 Bit overflow on previous } 
            begin 
              if BinStrToInt(PrevOctet)<>0 then 
                Result:=Result+Chr(BinStrToInt(PrevOctet)) 
              else Result:=Result+' ';           PrevOctet:=''; 
            end;       if Odd(Counter) then            { only take two nibbles at a time } 
            begin 
              OctetStr:=Copy(PDU,Counter,2); 
              OctetBin:=HexToBin(OctetStr);           Charbin:=''; 
              for Counter2:=1 to length(PrevOctet) do 
                Charbin:=Charbin+PrevOctet[Counter2];           for Counter2:=1 to 7-length(PrevOctet) do 
                Charbin:=OctetBin[8-Counter2+1]+Charbin;           if BinStrToInt(Charbin)<>0 then Result:=Result+Chr(BinStrToInt(CharBin)) 
                else Result:=Result+' ';           PrevOctet:=Copy(OctetBin,1,length(PrevOctet)+1); 
            end; 
        end; 
    end; 
    function ReverseStr(SourceStr : string) : string; 
    var Counter : integer; 
    begin 
      Result:='';   for Counter:=1 to length(SourceStr) do 
        Result:=SourceStr[Counter]+Result; 
    end; 
    function GB2UniCode(GB:string):string;
    var
      s: string;
      i, j, k: integer;
      a: array [1..160] of char;
    begin
      s:='';
      StringToWideChar(GB, @(a[1]), 500);
      i:=1;
      while ((a[i]<>#0) or (a[i+1]<>#0)) do begin
        j:=Integer(a[i]);
        k:=Integer(a[i+1]);
        s:=s+Copy(Format('%X ',[k*$100+j+$10000]) ,2,4);
        //S := S + Char(k)+Char(j);
        i:=i+2;
      end;
      Result:=s;
    end;
    function UniCode2GB(S : String):String;
    Var I: Integer;
    begin
       I :=  Length(S);
       while I >=4  do begin
         try
           Result :=WideChar(StrToInt('$'+S[I-3]+S[I-2]+S[I-1]+S[I]))+ Result;
         except end;
         I := I - 4;
       end;
    end;
    end.
      

  2.   

    AT COMMAND_v8.6,
    GSM_v0705,
    SMS PDU-mode是编程所需要的技术文件,在网上找找吧
      

  3.   

    上面的Dll我们公司一直在用,请放心.
      

  4.   

    关注。以后也许要用到。                     -------halfdream—-——======哈欠=====
      

  5.   

    Good Good Study And Day Day Up!!!!